context.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define CONTEXT_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"
#include "..\ARM.h"
#include <stdio.h>
#include <stdlib.h>
__asm int __get_CPSR(void)
{
mrs r0,cpsr
bx lr
}
__asm void __disable_interrupt(void)
{
aa mrs r0,cpsr
orr r0,r0,#0xc0
msr cpsr_c,r0
mrs r0,cpsr
ands r0,r0,#0xc0
beq aa
bx lr
}
__asm void __enable_interrupt(void)
{
mrs r0,cpsr
bic r0,r0,#0xc0
msr cpsr_c,r0
bx lr
}
#if defined(NUTOS)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/*!
* \brief Context switch frame layout.
*
* This is the layout of the stack after a thread's context has been
* switched-out. The stack pointer is stored in the thread info and
* points to this structure.
*/
typedef struct {
u_long csf_cpsr;
u_long csf_r4;
u_long csf_r5;
u_long csf_r6;
u_long csf_r7;
u_long csf_r8;
u_long csf_r9;
u_long csf_r10;
u_long csf_r11; /* AKA fp */
u_long csf_lr;
} SWITCHFRAME;
/*!
* \brief Thread entry frame layout.
*
* This is the stack layout being build to enter a new thread.
*/
typedef struct {
u_long cef_r0;
u_long cef_pc;
} ENTERFRAME;
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Enter a new thread.
*/
static __asm void NutThreadEntry(void) __attribute__ ((naked));
__asm void NutThreadEntry(void)
{
/* Load argument in r0 and jump to thread entry. */
// asm volatile ("ldmfd sp!, {r0, lr}\n\tbx lr":::"r0", "lr");
ldmfd sp!, {r0, lr}
BX LR
}
__asm void SaveStackPointer(uptr_t *pointer)
{
str sp, [r0]
BX LR
}
__asm void RestoreStackPointer(uptr_t *pointer)
{
ldr sp, [r0]
BX LR
}
/*!
* \brief Switch to another thread.
*
* Stop the current thread, saving its context. Then start the
* one with the highest priority, which is ready to run.
*
* Application programs typically do not call this function.
*
* \note CPU interrupts must be disabled before calling this function.
*
*/
void __asm NutThreadSwitch_1(void) __attribute__ ((naked));
void __asm NutThreadSwitch_1(void)
{
mov r1,lr
ldmia sp!, {r4, lr}
stmfd sp!, {r4-r11, lr}
mrs r0, cpsr
stmfd sp!, {r0}
BX r1
}
void __asm NutThreadSwitch_2(void) __attribute__ ((naked));
void __asm NutThreadSwitch_2(void)
{
ldmfd sp!, {r0}
bic r0, r0, #0xC0
msr SPSR_cxsf, r0
ldmfd sp!, {r4-r11, lr}
BX LR
}//CPSR_cxsf?SPSR_cxsf
void NutThreadSwitch(void) __attribute__ ((naked));
void NutThreadSwitch(void)
{
// asm("ldmia sp!, {r4, lr}");
// __asm__ __volatile__
// /* Save CPU context. */
// ("@ Save context\n\t"
// /* Save registers. */
// "stmfd sp!, {r4-r11, lr}\n\t"
// /* Save status. */
// "mrs r0, cpsr\n\t"
// /* */
// "stmfd sp!, {r0}\n\t"
// /* Save stack pointer. */
// "str sp, %[td_sp]"
// /* Output. */
// :
// /* Input. */
// :[td_sp] "o"(runningThread->td_sp)
// /* Clobbers. */
// :"r0", "memory");
/*
asm("stmfd sp!, {r4-r11, lr}"); // Save registers.
asm("mrs r0, cpsr"); // Save status.
asm("stmfd sp!, {r0}");*/
NutThreadSwitch_1();
SaveStackPointer(&runningThread->td_sp);
/* Select thread on top of the run queue. */
runningThread = runQueue;
runningThread->td_state = TDS_RUNNING;
// __asm__ __volatile__
// /* Restore context. */
// ("@ Reload context\n\t"
// /* Restore stack pointer. */
// "ldr sp, %[td_sp]\n\t"
// /* Get saved status... */
// "ldmfd sp!, {r0}\n\t"
// /* ...enable interrupts */
// "bic r0, r0, #0xC0\n\t"
// /* ...and save in spsr. */
// "msr spsr, r0\n\t"
// /* Restore registers. */
// "ldmfd sp!, {r4-r11, lr}\n\t"
// /* Restore status and return. */
// "movs pc, lr"
// /* Output. */
// :
// /* Input. */
// :[td_sp] "m"(runningThread->td_sp)
// /* Clobbers. */
// :"r0", "memory");
RestoreStackPointer(&runningThread->td_sp);
/*
asm("ldmfd sp!, {r0}"); // Get saved status...
asm("bic r0, r0, #0xC0"); // ...enable interrupts
asm("msr spsr, r0"); // ...and save in spsr.
asm("ldmfd sp!, {r4-r11, lr}"); // Restore registers.
asm("movs pc, lr"); // Restore status and return.
*/
NutThreadSwitch_2();
}
/*!
* \brief Create a new thread.
*
* If the current thread's priority is lower or equal than the default
* priority (64), then the current thread is stopped and the new one
* is started.
*
* \param name String containing the symbolic name of the new thread,
* up to 8 characters long.
* \param fn The thread's entry point, typically created by the
* THREAD macro.
* \param arg Argument pointer passed to the new thread.
* \param stackSize Number of bytes of the stack space allocated for
* the new thread.
*
* \note The thread must run in ARM mode. Thumb mode is not supported.
*
* \return Pointer to the NUTTHREADINFO structure or 0 to indicate an
* error.
*/
extern void led_led(void);
void __asm NutThreadCreate_1(void) __attribute__ ((naked));
void __asm NutThreadCreate_1(void)
{
ldmfd sp!, {r0}
bic r0, r0, #0xC0
msr SPSR_cxsf, r0
ldmfd sp!, {r4-r11, lr}
BX LR
}
NUTHANDLE NutThreadCreate(char * name, void (*fn) (void *), void *arg, size_t stackSize)
{
u_char *threadMem;
SWITCHFRAME *sf;
ENTERFRAME *ef;
NUTTHREADINFO *td;
// ch_20211229
#ifdef DEBUG_NUTOS
sysprintf("Enter NutThreadCreate()...\n");
#endif
/*
* Allocate stack and thread info structure in one block.
* We sill setup the following layout:
*
* Upper memory addresses.
*
* +--------------------+
* I I
* I NUTTHREADINFO I
* I I
* td -> +-----+--------------+ <- Stack top
* I I I
* I T I ENTERFRAME I
* I H I I
* ef -> I R +--------------+
* I E I I ^
* I A I SWITCHFRAME I I
* I D I I I pop moves up
* sf -> I +--------------+ <- Initial stack pointer
* I S I I I push moves down
* I T I Application I I
* I A I Stack I V
* I C I I
* I K I I
* threadMem -> +-----+--------------+ <- Stack bottom
*
* Lower memory addresses.
*/
if ((threadMem = NutHeapAlloc(stackSize + sizeof(NUTTHREADINFO))) == 0) {
return 0;
}
td = (NUTTHREADINFO *) (threadMem + stackSize);
ef = (ENTERFRAME *) ((uptr_t) td - sizeof(ENTERFRAME));
sf = (SWITCHFRAME *) ((uptr_t) ef - sizeof(SWITCHFRAME));
/*
* Set predefined values at the stack bottom. May be used to detect
* stack overflows.
*/
*((u_long *) threadMem) = DEADBEEF;
*((u_long *) (threadMem + 4)) = DEADBEEF;
*((u_long *) (threadMem + 8)) = DEADBEEF;
*((u_long *) (threadMem + 12)) = DEADBEEF;
/*
* Setup the entry frame to simulate C function entry.
*/
ef->cef_pc = (uptr_t) fn;
ef->cef_r0 = (uptr_t) arg;
/*
* Setup the switch frame.
*/
sf->csf_lr = (uptr_t) NutThreadEntry;
sf->csf_cpsr = ARM_CPSR_I_BIT | ARM_CPSR_F_BIT | ARM_MODE_SYS;
/*
* Initialize the thread info structure and insert it into the
* thread list and the run queue.
*/
memcpy(td->td_name, name, sizeof(td->td_name) - 1);
td->td_name[sizeof(td->td_name) - 1] = 0;
td->td_state = TDS_READY;
td->td_sp = (uptr_t) sf;
td->td_priority = 64;
td->td_memory = threadMem;
td->td_timer = 0;
td->td_queue = 0;
NutEnterCritical();
td->td_next = nutThreadList;
nutThreadList = td;
NutThreadAddPriQueue(td, (NUTTHREADINFO **) & runQueue);
// ch_20211229
#ifdef DEBUG_NUTOS
while (td)
{
sysprintf("%s\t", td->td_name);
td = td->td_next;
}
sysprintf("\n");
#endif
/*
* If no thread is running, then this is the first thread ever
* created. In Nut/OS, the idle thread is created first.
*/
if (runningThread == 0) {
/* This will never return. */
runningThread = runQueue;
runningThread->td_state = TDS_RUNNING;
// __asm__ __volatile__
// /* Load initial idle thread context. */
// ("@ Load context\n\t"
// /* Restore stack pointer. */
// "ldr sp, %[td_sp]\n\t"
// /* Get saved status... */
// "ldmfd sp!, {r0}\n\t"
// /* ...enable interrupts */
// "bic r0, r0, #0xC0\n\t"
// /* ...and save in spsr. */
// "msr spsr, r0\n\t"
// /* Restore registers. */
// "ldmfd sp!, {r4-r11, lr}\n\t"
// /* Restore status and return. */
// "movs pc, lr"
// /* Input. */
// :
// /* Output. */
// :[td_sp] "m" (runningThread->td_sp)
// /* Clobbers. */
// :"r0", "memory");
RestoreStackPointer(&runningThread->td_sp);
NutThreadCreate_1();
/*
asm("ldmfd sp!, {r0}"); // Get saved status...
asm("bic r0, r0, #0xC0"); // ...enable interrupts
asm("msr spsr, r0"); // ...and save in spsr.
asm("ldmfd sp!, {r4-r11, lr}"); // Restore registers.
asm("movs pc, lr"); // Restore status and return.
*/
}
/*
* If current context is not in front of the run queue (highest
* priority), then switch to the thread in front.
*/
if (runningThread != runQueue) {
runningThread->td_state = TDS_READY;
NutThreadSwitch();
}
NutExitCritical();
return td;
}
#endif
DMA.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Common.h"
#include "XCore.h"
#include "XProFile.h"
#include "XAppVer.h"
#include "XPrtEng.h"
#include "XParser.h"
#include "XComm.h"
#include "../device/USB/Device/N32903/UsbLibry.h"
#define DBG_PRINTF sysprintf
volatile unsigned int count=0;
static DMA_CALLBACK DMA_CallbackTab[4] = {0};
__align(32) UINT8 data[200];
void DMATest(void);
#define TEST_SIZE 1 * 1024
STATIC __align(4096) UINT8 WriteBuffer[TEST_SIZE];
UINT8 previous = 0;
UINT32 count_A = 0;
UINT8 flag = 0;
void DMA_ISR() {
if (inp32(REG_VDMA_ISR) & BIT31) {
sysPutChar('f');
if (inp32(REG_VDMA_ISR) & INTR1) {
if (inp32(REG_PDMA_ISR1) & EDMABLKD_IF) {
previous = 0;
outp32(REG_PDMA_ISR1, inp32(REG_PDMA_ISR1) | EDMABLKD_IF);
if (DMA_CallbackTab[0] != NULL) {
DMA_CallbackTab[0]();
}
} else if (inp32(REG_PDMA_ISR1) & EDMATABORT_IF) {
outp32(REG_PDMA_ISR1, EDMATABORT_IF);
}
} else if (inp32(REG_VDMA_ISR) & INTR2) {
if (inp32(REG_PDMA_ISR2) & EDMABLKD_IF) {
outp32(REG_PDMA_ISR2, EDMABLKD_IF);
DMA_CallbackTab[1]();
}
} else if (inp32(REG_VDMA_ISR) & INTR3) {
if (inp32(REG_PDMA_ISR3) & EDMABLKD_IF) {
outp32(REG_PDMA_ISR3, EDMABLKD_IF);
DMA_CallbackTab[2]();
}
} else if (inp32(REG_VDMA_ISR) & INTR4) {
if (inp32(REG_PDMA_ISR4) & EDMABLKD_IF) {
outp32(REG_PDMA_ISR4, EDMABLKD_IF);
DMA_CallbackTab[3]();
}
}
}
}
void DMA_Init() {
sysInstallISR(IRQ_LEVEL_7, IRQ_EDMA, (PVOID)DMA_ISR);
sysSetInterruptType(IRQ_EDMA, HIGH_LEVEL_SENSITIVE);
sysEnableInterrupt(IRQ_EDMA);
}
void DMA_Channel_Init(UINT8 channel,DMA_APB_DEVICE dev, DMA_APB_RW rw, DMA_DIRECTION_SELECT srcDir, DMA_DIRECTION_SELECT desDir) {
UINT32 u32SFR;
UINT8 shift;
UINT8 nShift;
outp32(REG_VDMA_CSR + channel * 0x100, inp32(REG_VDMA_CSR + channel * 0x100) | EDMACEN| TRIG_EN);
outp32(REG_AHBCLK, inp32(REG_AHBCLK) | (0x00000400 << channel));// open clk
//spiIoctl(0, SPI_SET_CLOCK, 48, 16000);
u32SFR = REG_VDMA_CSR + channel * 0x100;
outp32(u32SFR,(inp32(u32SFR) & ~APB_TWS) | (1 << 19));//8 bit
if (rw == DMA_WRITE_APB) {
outp32(u32SFR,(inp32(u32SFR) & ~MODE_SEL) | (2 << 2));//memory to device
shift = ((channel - 1) * 4 + 16);
nShift = ((channel - 1) * 4);
} else if (rw == DMA_READ_APB) {
outp32(u32SFR,(inp32(u32SFR) & ~MODE_SEL) | (1 << 2));//device to memory
shift = ((channel - 1) * 4);
nShift = ((channel - 1) * 4 + 16);
}
outp32(u32SFR, inp32(u32SFR) & ~EDMASG_EN);// disable scatter-gather function
outp32(u32SFR, inp32(u32SFR) & (~(3<<6)));
outp32(u32SFR, inp32(u32SFR) | (desDir << 6));
outp32(u32SFR, inp32(u32SFR) & (~(3<<4)));
outp32(u32SFR, inp32(u32SFR) | (srcDir << 4));
outp32(REG_EDSSR, inp32(REG_EDSSR) | (7 << nShift));
outp32(REG_EDSSR, inp32(REG_EDSSR) & (~(7 << shift)));//clear
outp32(REG_EDSSR, inp32(REG_EDSSR) | (dev << shift));// set channel
}
void DMA_Transfer_Init(UINT8 channel, UINT32 src, UINT32 dest, UINT32 len, DMA_CALLBACK callback) {
unsigned char *pSrc;
pSrc = (UINT8 *)((UINT32)WriteBuffer | NON_CACHE_BIT);
outp32(REG_VDMA_SAR + channel * 0x100, (UINT32)pSrc);
outp32(REG_VDMA_DAR + channel * 0x100, dest);
outp32(REG_VDMA_BCR + channel * 0x100, len);
outp32(REG_VDMA_IER + channel * 0x100, BLKD_IE);
DMA_CallbackTab[channel - 1] = callback;
}
void DMA_Transfer(UINT8 channel, DMA_APB_DEVICE dev, DMA_APB_RW rw) {
switch(dev) {
case DMA_SPIMS0:
if (rw == DMA_READ_APB) {
outp32(REG_SPI0_EDMA, 0x03 | EDMA_GO);
outp32(REG_SPI0_CNTRL, inp32(REG_SPI0_CNTRL) |GO_BUSY);
} else if (rw == DMA_WRITE_APB) {
outp32(REG_SPI0_EDMA, 0x01 | EDMA_GO);
outp32(REG_SPI0_CNTRL, inp32(REG_SPI0_CNTRL) |GO_BUSY);
}
break;
}
}
void DMA_TransferClose(UINT8 channel) {
outp32(REG_VDMA_ISR + channel * 0x100, inp32(REG_VDMA_ISR + channel * 0x100) | (EDMASG_IF | EDMABLKD_IF | EDMATABORT_IF));
outp32(REG_VDMA_IER + channel * 0x100, inp32(REG_VDMA_IER + channel * 0x100) & ~(SG_IEN | WAR_IE | BLKD_IE | EDMATABORT_IE));
outp32(REG_VDMA_CSR + channel * 0x100, inp32(REG_VDMA_CSR + channel * 0x100) & ~EDMACEN);
outp32(REG_AHBCLK,inp32(REG_AHBCLK) & ~(0x00000400 << channel));
}
void SPI_Init() {
UINT16 loop = 500;
outpw(REG_APBCLK, inpw(REG_APBCLK) | SPIMS0_CKE); // turn on SPI clk
outpw(REG_APBIPRST, inpw(REG_APBIPRST) | SPI0RST);
outpw(REG_APBIPRST, inpw(REG_APBIPRST) & ~SPI0RST);
while (loop --);
outpw(REG_SPI0_CNTRL, inpw(REG_SPI0_CNTRL) | (1 << 11));//clk idle high
outpw(REG_SPI0_CNTRL, inpw(REG_SPI0_CNTRL) & (~(1 << 10)));//MSB first
outpw(REG_SPI0_CNTRL, inpw(REG_SPI0_CNTRL) & (~(0x1f << 3)));
outpw(REG_SPI0_CNTRL, inpw(REG_SPI0_CNTRL) | (8 << 3));//8 BIT
outpw(REG_SPI0_CNTRL, inpw(REG_SPI0_CNTRL) & (~(1 << 2)));//tx on rising
spiIoctl(0, SPI_SET_CLOCK, 96, 8000);
spiTxLen(0, 0, 8);
}
void DMACb() {
unsigned short val;
UINT32 loop = 1280 * 2;
//sysprintf("f\n");
//count_A --;
while(loop --);
TPH_SpiEnd();
TPH_SpiStart((UINT32)data, 108, 1,DMACb);
sysPutChar('b');
sysPutChar('\n');
//DMA_Transfer_Init(1, (UINT32)data, REG_SPI0_TX0, 108, DMACb);
//DMA_Transfer(1, DMA_SPIMS0, DMA_WRITE_APB);
}
void TIME_cb() {
//sysprintf("TIME_CB\n");
}
void Test()
{
UINT32 loop = 1280;
//sysPutChar('e');
//sysprintf("e\n");
//DMA_Transfer_Init(1, (UINT32)data, REG_SPI0_TX0, 108, DMACb);
//DMA_Transfer(1, DMA_SPIMS0, DMA_WRITE_APB);
while(loop --);
TPH_SpiStart((UINT32)data, 108, 1,DMACb);
sysPutChar('a');
//while(loop --);
//sysprintf("%d\n", count_A);
//sysPutChar('0' + count_A);
//count_A ++;
}
void t1_cb() {
static UINT32 count = 0;
count ++;
}
void DemoAPI_Timer0(void)
{
// unsigned int volatile i;
volatile unsigned int btime, etime, tmp, tsec;
volatile UINT32 u32TimeOut = 0;
UINT32 u32ExtFreq;
u32ExtFreq = sysGetExternalClock()*1000;
DBG_PRINTF("Timer 0 Test...\n");
sysSetTimerReferenceClock(TIMER0, u32ExtFreq); //External Crystal
sysStartTimer(TIMER0, 10000, PERIODIC_MODE); /* 100 ticks/per sec ==> 1tick/10ms */
tmp = sysSetTimerEvent(TIMER0, 25, (PVOID)Test); /* 100 ticks = 1s call back */
sysSetTimerReferenceClock(TIMER1, u32ExtFreq); //External Crystal
sysStartTimer(TIMER1, 1000, PERIODIC_MODE); /* 100 ticks/per sec ==> 1tick/10ms */
tmp = sysSetTimerEvent(TIMER1, 10, (PVOID)t1_cb); /* 100 ticks = 1s call back */
}
void DMATest(void) {
UINT16 index;
UINT32 u32ExtFreq;
DemoAPI_Timer0();
/*
for (index = 0; index < 1024; index ++) {
data[index] = 0x55;
}
*/
SPI_Init();
DMA_Init();
//DMA_Channel_Init(1, DMA_SPIMS0, DMA_WRITE_APB, DMA_DIRECTION_INCREMENTED, DMA_DIRECTION_FIXED);
//DMA_Transfer_Init(1, (UINT32)data, REG_SPI0_TX0, 108, DMACb);
//DMA_Transfer(1, DMA_SPIMS0, DMA_WRITE_APB);
}
DMA.H 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef __DMA_H__
#define __DMA_H__
typedef enum
{
DMA_SPIMS0=0,
DMA_SPIMS1,
DMA_UART0,
DMA_UART1,
DMA_ADC,
DMA_DIS
}DMA_APB_DEVICE;
typedef enum
{
DMA_READ_APB=0,
DMA_WRITE_APB
}DMA_APB_RW;
typedef enum
{
DMA_DIRECTION_INCREMENTED =0,
DMA_DIRECTION_DECREMENTED,
DMA_DIRECTION_FIXED,
DMA_DIRECTION_WRAPAROUND
}DMA_DIRECTION_SELECT;
typedef void (*DMA_CALLBACK)();
void DMA_Init(void);
void DMA_Channel_Init(UINT8 channel,DMA_APB_DEVICE dev, DMA_APB_RW rw, DMA_DIRECTION_SELECT srcDir, DMA_DIRECTION_SELECT desDir);
void DMA_Transfer_Init(UINT8 channel, UINT32 src, UINT32 dest, UINT32 len, DMA_CALLBACK callback);
void DMA_Transfer(UINT8 channel, DMA_APB_DEVICE dev, DMA_APB_RW rw);
void DMA_TransferClose(UINT8 channel);
void SPI_Init(void);
#endif
DrvEDMA.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/****************************************************************
* *
* Copyright (c) Nuvoton Technology Corp. All rights reserved. *
* *
****************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "wblib.h"
#include "DrvEDMA.h"
static PFN_DRVEDMA_CALLBACK g_pfnEDMACallback[MAX_CHANNEL_NUM+1][4] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
#define MAX_GS_TRANSFER_SIZE 32*1024
void DrvEDMA_EnableScatterGather(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
void DrvEDMA_DisableScatterGather(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
UINT32
DrvEDMA_Open(void)
{
// 1.Check I/O pins. If I/O pins are used by other IPs, return error code.
// 2.Enable IPˇs clock --> Enable Channel clock in DrvEDMA_SetCHOperation( ) function
// 3.Reset IP
// 4.Configure IP according to inputted arguments.
// 5.Enable IP I/O pins
// 6.Return 0 to present success
return E_SUCCESS;
}
void DrvEDMA_Close(void)
{
UINT32 u32Mask;
// 1.Disable IP I/O pins
// 2.Disable IPˇs clock --> Disable Channel Clock in DrvEDMA_SetCHOperation( ) function
u32Mask = EDMA0_CKE | EDMA1_CKE | EDMA2_CKE | EDMA3_CKE | EDMA4_CKE;
outp32(REG_AHBCLK,inp32(REG_AHBCLK) & ~u32Mask);
}
// Get Channel Enable/Disable status
BOOL
DrvEDMA_IsCHBusy(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
if (inp32(u32SFR) & TRIG_EN)
return TRUE;
else
return FALSE;
}
// Set Channel Enable/Disable & Enable Channel Clock
void DrvEDMA_EnableCH(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_OPERATION eOP
)
{
UINT32 u32SFR,u32Mask;
u32Mask = 0x00000400 << eChannel;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
if (eOP == eDRVEDMA_DISABLE)
{
outp32(u32SFR, inp32(u32SFR) & ~EDMACEN);
outp32(REG_AHBCLK,inp32(REG_AHBCLK) & ~u32Mask); // Disable Channel Clock
}
else
{
outp32(REG_AHBCLK,inp32(REG_AHBCLK) | u32Mask); // Enable Channel Clock
outp32(u32SFR, inp32(u32SFR) | EDMACEN);
}
}
// Get Channel Enable/Disable status
BOOL
DrvEDMA_IsEnabledCH(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
return inp32(u32SFR) & EDMACEN;
}
// Set Source/Destination Address and Direction and Transfer Length for Channelx
ERRCODE
DrvEDMA_SetTransferSetting(
E_DRVEDMA_CHANNEL_INDEX eChannel,
S_DRVEDMA_CH_ADDR_SETTING* psSrcAddr,
S_DRVEDMA_CH_ADDR_SETTING* psDestAddr,
UINT32 u32TransferLength
)
{
UINT32 u32SFR, u32Value;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
DrvEDMA_DisableScatterGather(eChannel);
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
u32Value = inp32(u32SFR);
outp32(REG_VDMA_SAR + eChannel * 0x100, psSrcAddr->u32Addr);
u32Value = (u32Value & ~SAD_SEL) | (psSrcAddr->eAddrDirection << SOURCE_DIRECTION_BIT);
outp32(REG_VDMA_DAR + eChannel * 0x100, psDestAddr->u32Addr);
u32Value = (u32Value & ~DAD_SEL) | (psDestAddr->eAddrDirection << DESTINATION_DIRECTION_BIT);
outp32(u32SFR,u32Value);
if (u32TransferLength > MAX_TRANSFER_BYTE_COUNT)
return E_DRVEDMA_FALSE_INPUT;
outp32(REG_VDMA_BCR + eChannel * 0x100,u32TransferLength);
return E_SUCCESS;
}
// Get Source/Destination Address and Direction from Channelx
ERRCODE
DrvEDMA_GetTransferSetting(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_TARGET eTarget,
UINT32* pu32Addr,
E_DRVEDMA_DIRECTION_SELECT* peDirection
)
{
UINT32 u32SFR, u32Value;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
if ((eTarget != eDRVEDMA_TARGET_SOURCE) && (eTarget != eDRVEDMA_TARGET_DESTINATION))
return E_DRVEDMA_FALSE_INPUT;
u32Value = inp32(u32SFR);
if (eTarget == eDRVEDMA_TARGET_SOURCE)
{
*pu32Addr = inp32(REG_VDMA_SAR + eChannel * 0x100);
*peDirection = (u32Value & SAD_SEL) >> SOURCE_DIRECTION_BIT;
}
else
{
*pu32Addr = inp32(REG_VDMA_DAR + eChannel * 0x100);
*peDirection = (u32Value & DAD_SEL) >> DESTINATION_DIRECTION_BIT;
}
return E_SUCCESS;
}
// Get Transfer Length from Channelx
ERRCODE
DrvEDMA_GetTransferLength(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32* pu32TransferLength
)
{
UINT32 u32SFR;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_BCR + eChannel * 0x100;
*pu32TransferLength = inp32(u32SFR);
return E_SUCCESS;
}
// Set APB Transfer Width for Channelx
ERRCODE
DrvEDMA_SetAPBTransferWidth(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_TRANSFER_WIDTH eTransferWidth
)
{
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel ==0))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
outp32(u32SFR,(inp32(u32SFR) & ~APB_TWS) | (eTransferWidth << TRANSFER_WIDTH_BIT));
return E_SUCCESS;
}
// Get Transfer Width from Channelx
ERRCODE
DrvEDMA_GetAPBTransferWidth(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_TRANSFER_WIDTH* peTransferWidth
)
{
UINT32 u32SFR;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
*peTransferWidth = (inp32(u32SFR) & APB_TWS) >> TRANSFER_WIDTH_BIT;
return E_SUCCESS;
}
// Select EDMA channel for APB Device
ERRCODE
DrvEDMA_SetCHForAPBDevice(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_APB_DEVICE eDevice,
E_DRVEDMA_APB_RW eRWAPB
)
{
UINT32 u32Value,u32Mask,i,u32OrMask;
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel ==0))
return E_DRVEDMA_FALSE_INPUT;
if ((eRWAPB == eDRVEDMA_WRITE_APB) && (eDevice == eDRVEDMA_ADC))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
// Let Tx and Rx does not use the same channel
if (eRWAPB == eDRVEDMA_WRITE_APB)
{
outp32(u32SFR,(inp32(u32SFR) & ~MODE_SEL) | (eDRVEDMA_MEMORY_TO_DEVICE << MODE_SELECT_BIT));
u32Mask = 0x000F0000 << ((eChannel-1)*4);
u32OrMask = 0x0007 << ((eChannel-1)*4);
}
else
{
outp32(u32SFR,(inp32(u32SFR) & ~MODE_SEL) | (eDRVEDMA_DEVICE_TO_MEMORY << MODE_SELECT_BIT));
u32Mask = 0x0000000F << ((eChannel-1)*4);
u32OrMask = 0x00070000 << ((eChannel-1)*4);
}
u32Value = inp32(REG_EDSSR) & ~u32Mask;
if ((eDevice == eDRVEDMA_SPIMS0) || (eDevice == eDRVEDMA_SPIMS1))
u32Value &= ~u32OrMask;
else
u32Value |= u32OrMask;
// let Tx or Rx does not use two channel concurrently
if (eRWAPB == eDRVEDMA_WRITE_APB)
{
u32Mask = 0x070000;
for(i=1;i<=4;i++)
{
if (i != eChannel)
{
if (((u32Value & u32Mask)>>((i-1)*4+16)) == eDevice)
{
u32Value |= u32Mask;
if ((eDevice == eDRVEDMA_SPIMS0) || (eDevice == eDRVEDMA_SPIMS1))
u32Value |= 0x07 << ((i-1)*4);
}
}
u32Mask <<= 4;
}
u32Value |= eDevice << ((eChannel-1)*4 + 16);
// TX and RX use same channel for SPIM0 & 1
if ((eDevice == eDRVEDMA_SPIMS0) || (eDevice == eDRVEDMA_SPIMS1))
u32Value |= eDevice << ((eChannel-1)*4);
}
else
{
u32Mask = 0x07;
for(i=1;i<=4;i++)
{
if (i != eChannel)
{
if (((u32Value & u32Mask)>>(i-1)*4) == eDevice)
{
u32Value |= u32Mask;
if ((eDevice == eDRVEDMA_SPIMS0) || (eDevice == eDRVEDMA_SPIMS1))
u32Value |= 0x070000 << ((i-1)*4);
}
}
u32Mask <<= 4;
}
u32Value |= eDevice << ((eChannel-1)*4);
// TX and RX use same channel for SPIM0 & 1
if ((eDevice == eDRVEDMA_SPIMS0) || (eDevice == eDRVEDMA_SPIMS1))
u32Value |= eDevice << ((eChannel-1)*4+16);
}
outp32(REG_EDSSR,u32Value);
return E_SUCCESS;
}
// Get EDMA channel for APB Device
E_DRVEDMA_CHANNEL_INDEX
DrvEDMA_GetCHForAPBDevice(
E_DRVEDMA_APB_DEVICE eDevice,
E_DRVEDMA_APB_RW eRWAPB
)
{
UINT32 u32Value,i;
if ((eDevice < eDRVEDMA_SPIMS0) || (eDevice > eDRVEDMA_ADC))
return E_DRVEDMA_FALSE_INPUT;
if (eRWAPB == eDRVEDMA_WRITE_APB)
{
u32Value = inp32(REG_EDSSR)>>16;
}
else
{
u32Value = inp32(REG_EDSSR);
}
for(i=1;i<=4;i++)
{
if (((u32Value >> (i-1)*4) & 0x07) == eDevice)
return i;
}
return 0;
}
// Set Wrap Around Transfer Byte count interrupt Select for Channelx
ERRCODE
DrvEDMA_SetWrapIntType(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_WRAPAROUND_SELECT eType
)
{
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel == 0))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
if (eType > 0x0F)
return E_DRVEDMA_FALSE_INPUT;
outp32(u32SFR,(inp32(u32SFR) & ~WAR_BCR_SEL) | (eType<<12));
return E_SUCCESS;
}
// Get Wrap Around Transfer Byte count interrupt Select from Channelx
E_DRVEDMA_WRAPAROUND_SELECT
DrvEDMA_GetWrapIntType(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel == 0))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
return (inp32(u32SFR) & WAR_BCR_SEL )>> 12;
}
// Software reset Channelx
ERRCODE
DrvEDMA_CHSoftwareReset(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
outp32(u32SFR, inp32(u32SFR) | SW_RST);
return E_SUCCESS;
}
// Enable EDMA data read or write Transfer
ERRCODE
DrvEDMA_CHEnablelTransfer(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
outp32(u32SFR, inp32(u32SFR) | TRIG_EN | EDMACEN);
return E_SUCCESS;
}
// Get Current Source Address from Channelx
UINT32
DrvEDMA_GetCurrentSourceAddr(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_CSAR + eChannel * 0x100;
return inp32(u32SFR);
}
// Get Current Destination Address from Channelx
UINT32
DrvEDMA_GetCurrentDestAddr(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_CDAR + eChannel * 0x100;
return inp32(u32SFR);
}
// Get Current Transfer Count from Channelx
UINT32
DrvEDMA_GetCurrentTransferCount(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_CBCR + eChannel * 0x100;
return inp32(u32SFR);
}
// Enable Interrupt for Channelx
ERRCODE
DrvEDMA_EnableInt(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_ENABLE eIntSource
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_IER + eChannel * 0x100;
if ((eIntSource <1) || (eIntSource >15))
return E_DRVEDMA_FALSE_INPUT;
outp32(u32SFR, inp32(u32SFR) | eIntSource);
return E_SUCCESS;
}
// Disable Interrupt for Channelx
void DrvEDMA_DisableInt(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_ENABLE eIntSource
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_IER + eChannel * 0x100;
outp32(u32SFR, inp32(u32SFR) & ~eIntSource);
}
// Check if the specified interrupt source is enabled in Channelx
UINT32
DrvEDMA_IsIntEnabled(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_ENABLE eIntSource
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_ISR + eChannel * 0x100;
switch(eIntSource)
{
case eDRVEDMA_TABORT:
return inp32(u32SFR) & EDMATABORT_IE;
break;
case eDRVEDMA_BLKD:
return inp32(u32SFR) & BLKD_IE;
break;
case eDRVEDMA_WAR:
return inp32(u32SFR) & WAR_IE;
break;
case eDRVEDMA_SG:
return inp32(u32SFR) & SG_IEN;
break;
default :
return E_DRVEDMA_FALSE_INPUT;
}
}
// Clear Interrupt Status for Channelx
void DrvEDMA_ClearInt(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_FLAG eIntFlag
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_ISR + eChannel * 0x100;
outp32(u32SFR, eIntFlag);
}
BOOL
DrvEDMA_PollInt(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_FLAG eIntFlag
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_ISR + eChannel * 0x100;
return inp32(u32SFR) & eIntFlag;
}
// Set Color Format Transform for Channel0
ERRCODE
DrvEDMA_SetColorTransformFormat(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_COLOR_FORMAT eSourceFormat,
E_DRVEDMA_COLOR_FORMAT eDestFormat
)
{
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel == 1) || (eChannel == 2) || (eChannel == 3) || (eChannel == 4))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
outp32(u32SFR, (inp32(u32SFR) & ~(SOUR_FORMAT | DEST_FORMAT)) | eSourceFormat<<24 | eDestFormat<<16);
return E_SUCCESS;
}
// Get Color Format Transform from Channel0
void DrvEDMA_GetColorTransformFormat(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_COLOR_FORMAT* peSourceFormat,
E_DRVEDMA_COLOR_FORMAT* peDestFormat
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
*peSourceFormat = (inp32(u32SFR) & SOUR_FORMAT) >> 24;
*peDestFormat = (inp32(u32SFR) & DEST_FORMAT) >> 16;
}
ERRCODE
DrvEDMA_SetColorTransformOperation(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_OPERATION eColorSpaceTran,
E_DRVEDMA_OPERATION eStrideMode
)
{
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel == 1) || (eChannel == 2) || (eChannel == 3) || (eChannel == 4))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
outp32(u32SFR, (inp32(u32SFR) & ~(COL_TRA_EN | STRIDE_EN)) | eColorSpaceTran<<1 | eStrideMode);
return E_SUCCESS;
}
void DrvEDMA_GetColorTransformOperation(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_OPERATION* peColorSpaceTran,
E_DRVEDMA_OPERATION* peStrideMode
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
*peColorSpaceTran = (inp32(u32SFR) & COL_TRA_EN) >> 1;
*peStrideMode = inp32(u32SFR) & STRIDE_EN ;
}
// Set Source Stride Transfer Byte Count & Offset Byte Length
// Only Channel0 support this function
ERRCODE
DrvEDMA_SetSourceStride(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32StrideByteCount,
UINT32 u32OffsetByteLength
)
{
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel == 1) || (eChannel == 2) || (eChannel == 3) || (eChannel == 4))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_SASOCR + eChannel * 0x100;
outp32(u32SFR,(u32StrideByteCount<<16) |u32OffsetByteLength);
return E_SUCCESS;
}
// Get Source/Destination Stride Transfer Byte Count & Offset Byte Length
void DrvEDMA_GetSourceStride(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32* pu32StrideByteCount,
UINT32* pu32OffsetByteLength
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_SASOCR + eChannel * 0x100;
*pu32StrideByteCount = (inp32(u32SFR) & STBC) >> 16;
*pu32OffsetByteLength = (inp32(u32SFR) & SASTOBL);
}
// Set Destination Stride Transfer Byte Count & Offset Byte Length
// Only Channel0 support this function
ERRCODE
DrvEDMA_SetDestinationStrideOffset(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32OffsetByteLength
)
{
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel == 1) || (eChannel == 2) || (eChannel == 3) || (eChannel == 4))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_DASOCR + eChannel * 0x100;
outp32(u32SFR,u32OffsetByteLength & DASTOBL);
return E_SUCCESS;
}
// Get Destination Stride Offset Byte Length
void DrvEDMA_GetDestinationStrideOffset(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32* pu32OffsetByteLength
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_DASOCR + eChannel * 0x100;
*pu32OffsetByteLength = (inp32(u32SFR) & DASTOBL);
}
// Set Channel0 Clamping function
ERRCODE
DrvEDMA_SetClamping(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_OPERATION eOP
)
{
UINT32 u32SFR;
if ((eChannel > MAX_CHANNEL_NUM) || (eChannel == 1) || (eChannel == 2) || (eChannel == 3) || (eChannel == 4))
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
if (eOP == eDRVEDMA_DISABLE)
outp32(u32SFR, inp32(u32SFR) & ~CLAMPING_EN);
else
outp32(u32SFR, inp32(u32SFR) | CLAMPING_EN);
return E_SUCCESS;
}
// Get Channel0 Clamping status
E_DRVEDMA_OPERATION
DrvEDMA_GetClamping(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
return (inp32(u32SFR) & CLAMPING_EN) >> 7;
}
// Get Channel 1 ~ 4 Internal Buffer Pointer
UINT32
DrvEDMA_GetInternalBufPointer(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
//if ((eChannel > MAX_CHANNEL_NUM) || (eChannel == 0))
// return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_PDMA_POINT1 + (eChannel-1) * 0x100;
return (inp32(u32SFR) & PDMA_POINT);
}
// Get Shared Buffer Content from Channelx
UINT32
DrvEDMA_GetSharedBufData(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32BufIndex
)
{
UINT32 u32SFR;
u32SFR = REG_EDMA_SBUF0_C0 + eChannel * 0x100 + u32BufIndex * 4;
return inp32(u32SFR);
}
// EDMA ISR
void DrvEDMA_ISR(void)
{
UINT32 u32IntStatus;
UINT32 u32WraparoundStatus;
if (inp32(REG_VDMA_ISR) & BIT31)
{
if (inp32(REG_VDMA_ISR) & INTR0)
{
u32IntStatus = inp32(REG_VDMA_ISR) & inp32(REG_VDMA_IER);
if (u32IntStatus & EDMATABORT_IF)
{
outp32(REG_VDMA_ISR,EDMATABORT_IF);
if (g_pfnEDMACallback[0][0] != 0)
(*g_pfnEDMACallback[0][0])(0);
}
else
{
if (u32IntStatus & EDMABLKD_IF)
{
outp32(REG_VDMA_ISR,EDMABLKD_IF);
if (g_pfnEDMACallback[0][1] != 0)
(*g_pfnEDMACallback[0][1])(0);
}
else if (u32IntStatus & EDMASG_IF)
{
outp32(REG_VDMA_ISR,EDMASG_IF);
if (g_pfnEDMACallback[0][3] != 0)
(*g_pfnEDMACallback[0][3])(0);
}
}
}
else if (inp32(REG_VDMA_ISR) & INTR1)
{
if (inp32(REG_PDMA_IER1) & WAR_IE)
u32IntStatus = inp32(REG_PDMA_ISR1) & (inp32(REG_PDMA_IER1) | 0x0F00);
else
u32IntStatus = inp32(REG_PDMA_ISR1) & inp32(REG_PDMA_IER1);
if (u32IntStatus & EDMATABORT_IF)
{
outp32(REG_PDMA_ISR1,EDMATABORT_IF);
if (g_pfnEDMACallback[1][0] != 0)
(*g_pfnEDMACallback[1][0])(0);
}
else
{
if (u32IntStatus & EDMABLKD_IF)
{
outp32(REG_PDMA_ISR1,EDMABLKD_IF);
if (g_pfnEDMACallback[1][1] != 0)
(*g_pfnEDMACallback[1][1])(0);
}
else if (u32IntStatus & EDMASG_IF)
{
outp32(REG_PDMA_ISR1,EDMASG_IF);
if (g_pfnEDMACallback[1][3] != 0)
(*g_pfnEDMACallback[1][3])(0);
}
else
{
u32WraparoundStatus = inp32(REG_PDMA_ISR1) & 0x0F00;
if (u32WraparoundStatus)
{
if (u32WraparoundStatus & 0x0200)
u32WraparoundStatus = 0x0200;
else if (u32WraparoundStatus & 0x0400)
u32WraparoundStatus = 0x0400;
else if (u32WraparoundStatus & 0x0800)
u32WraparoundStatus = 0x0800;
else
u32WraparoundStatus = 0x0100;
outp32(REG_PDMA_ISR1,u32WraparoundStatus);
if (g_pfnEDMACallback[1][2] != 0)
(*g_pfnEDMACallback[1][2])(u32WraparoundStatus);
}
}
}
}
else if (inp32(REG_VDMA_ISR) & INTR2)
{
if (inp32(REG_PDMA_IER2) & WAR_IE)
u32IntStatus = inp32(REG_PDMA_ISR2) & (inp32(REG_PDMA_IER2) | 0x0F00);
else
u32IntStatus = inp32(REG_PDMA_ISR2) & inp32(REG_PDMA_IER2);
if (u32IntStatus & EDMATABORT_IF)
{
outp32(REG_PDMA_ISR2,EDMATABORT_IF);
if (g_pfnEDMACallback[2][0] != 0)
(*g_pfnEDMACallback[2][0])(0);
}
else
{
if (u32IntStatus & EDMABLKD_IF)
{
outp32(REG_PDMA_ISR2,EDMABLKD_IF);
if (g_pfnEDMACallback[2][1] != 0)
(*g_pfnEDMACallback[2][1])(0);
}
else if (u32IntStatus & EDMASG_IF)
{
outp32(REG_PDMA_ISR2,EDMASG_IF);
if (g_pfnEDMACallback[2][3] != 0)
(*g_pfnEDMACallback[2][3])(0);
}
else
{
u32WraparoundStatus = inp32(REG_PDMA_ISR2) & 0x0F00;
if (u32WraparoundStatus)
{
if (u32WraparoundStatus & 0x0200)
u32WraparoundStatus = 0x0200;
else if (u32WraparoundStatus & 0x0400)
u32WraparoundStatus = 0x0400;
else if (u32WraparoundStatus & 0x0800)
u32WraparoundStatus = 0x0800;
else
u32WraparoundStatus = 0x0100;
outp32(REG_PDMA_ISR2,u32WraparoundStatus);
if (g_pfnEDMACallback[2][2] != 0)
(*g_pfnEDMACallback[2][2])(u32WraparoundStatus);
}
}
}
}
else if (inp32(REG_VDMA_ISR) & INTR3)
{
if (inp32(REG_PDMA_IER3) & WAR_IE)
u32IntStatus = inp32(REG_PDMA_ISR3) & (inp32(REG_PDMA_IER3) | 0x0F00);
else
u32IntStatus = inp32(REG_PDMA_ISR3) & inp32(REG_PDMA_IER3);
if (u32IntStatus & EDMATABORT_IF)
{
outp32(REG_PDMA_ISR3,EDMATABORT_IF);
if (g_pfnEDMACallback[3][0] != 0)
(*g_pfnEDMACallback[3][0])(0);
}
else
{
if (u32IntStatus & EDMABLKD_IF)
{
outp32(REG_PDMA_ISR3,EDMABLKD_IF);
if (g_pfnEDMACallback[3][1] != 0)
(*g_pfnEDMACallback[3][1])(0);
}
else if (u32IntStatus & EDMASG_IF)
{
outp32(REG_PDMA_ISR3,EDMASG_IF);
if (g_pfnEDMACallback[3][3] != 0)
(*g_pfnEDMACallback[3][3])(0);
}
else
{
u32WraparoundStatus = inp32(REG_PDMA_ISR3) & 0x0F00;
if (u32WraparoundStatus)
{
if (u32WraparoundStatus & 0x0200)
u32WraparoundStatus = 0x0200;
else if (u32WraparoundStatus & 0x0400)
u32WraparoundStatus = 0x0400;
else if (u32WraparoundStatus & 0x0800)
u32WraparoundStatus = 0x0800;
else
u32WraparoundStatus = 0x0100;
outp32(REG_PDMA_ISR3,u32WraparoundStatus);
if (g_pfnEDMACallback[3][2] != 0)
(*g_pfnEDMACallback[3][2])(u32WraparoundStatus);
}
}
}
}
else
{
if (inp32(REG_PDMA_IER4) & WAR_IE)
u32IntStatus = inp32(REG_PDMA_ISR4) & (inp32(REG_PDMA_IER4) | 0x0F00);
else
u32IntStatus = inp32(REG_PDMA_ISR4) & inp32(REG_PDMA_IER4);
if (u32IntStatus & EDMATABORT_IF)
{
outp32(REG_PDMA_ISR4,EDMATABORT_IF);
if (g_pfnEDMACallback[4][0] != 0)
(*g_pfnEDMACallback[4][0])(0);
}
else
{
if (u32IntStatus & EDMABLKD_IF)
{
outp32(REG_PDMA_ISR4,EDMABLKD_IF);
if (g_pfnEDMACallback[4][1] != 0)
(*g_pfnEDMACallback[4][1])(0);
}
else if (u32IntStatus & EDMASG_IF)
{
outp32(REG_PDMA_ISR4,EDMASG_IF);
if (g_pfnEDMACallback[4][3] != 0)
(*g_pfnEDMACallback[4][3])(0);
}
else
{
u32WraparoundStatus = inp32(REG_PDMA_ISR4) & 0x0F00;
if (u32WraparoundStatus)
{
if (u32WraparoundStatus & 0x0200)
u32WraparoundStatus = 0x0200;
else if (u32WraparoundStatus & 0x0400)
u32WraparoundStatus = 0x0400;
else if (u32WraparoundStatus & 0x0800)
u32WraparoundStatus = 0x0800;
else
u32WraparoundStatus = 0x0100;
outp32(REG_PDMA_ISR4,u32WraparoundStatus);
if (g_pfnEDMACallback[4][2] != 0)
(*g_pfnEDMACallback[4][2])(u32WraparoundStatus);
}
}
}
}
}
}
void DrvEDMA_Spi(PFN_DRVEDMA_CALLBACK irq1)
{
g_pfnEDMACallback[1][1] = irq1;
sysInstallISR(IRQ_LEVEL_2, IRQ_EDMA, (PVOID)DrvEDMA_ISR);
}
// Install Call Back Function for Channelx & Interrupt source
ERRCODE
DrvEDMA_InstallCallBack(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_ENABLE eIntSource,
PFN_DRVEDMA_CALLBACK pfncallback,
PFN_DRVEDMA_CALLBACK *pfnOldcallback
)
{
UINT32 u32SFR, index;
u32SFR = REG_VDMA_IER + eChannel * 0x100;
if (eChannel > MAX_CHANNEL_NUM)
return E_DRVEDMA_FALSE_INPUT;
if ((eIntSource !=1) && (eIntSource !=2) && (eIntSource !=4) && (eIntSource !=8))
return E_DRVEDMA_FALSE_INPUT;
/*
if (*pfnOldcallback != 0)
*pfnOldcallback = g_pfnEDMACallback[eChannel][eIntSource>>1];
///g_pfnEDMACallback[eChannel][eIntSource>>1] = pfncallback;
for(i=0; i<4; i++)
{
if((eIntSource>>i) & 0x01)
g_pfnEDMACallback[eChannel][i] = pfncallback;
}
*/
for (index=0; index<4; index++)
if ((1<<index) == eIntSource)
break;
if (pfnOldcallback != NULL)
*pfnOldcallback = g_pfnEDMACallback[eChannel][index];
g_pfnEDMACallback[eChannel][index] = pfncallback;
sysInstallISR(IRQ_LEVEL_1, IRQ_EDMA, (PVOID)DrvEDMA_ISR);
sysSetInterruptType(IRQ_EDMA, HIGH_LEVEL_SENSITIVE);
sysEnableInterrupt(IRQ_EDMA);
return E_SUCCESS;
}
// Get Information about Scatter Gather Descript Table size and Max Transfer Size per Descript Table
void DrvEDMA_GetScatterGatherInfo(
UINT32 *pu32TblSize,
UINT32 *pu32MaxTransferBytePerTbl
)
{
*pu32TblSize = sizeof(S_DRVEDMA_DESCRIPT_FORMAT);
*pu32MaxTransferBytePerTbl = MAX_GS_TRANSFER_SIZE;
return;
}
// Set Scatter Gather Descript Format Table Start Address
void DrvEDMA_SetScatterGatherTblStartAddr(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32TblStartAddr
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_SGAR + eChannel * 0x100;
outp32(u32SFR, u32TblStartAddr);
}
// Enable Scatter Gather Function
void DrvEDMA_EnableScatterGather(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
outp32(u32SFR, inp32(u32SFR)| EDMASG_EN);
}
// Disable Scatter Gather Function
void DrvEDMA_DisableScatterGather(
E_DRVEDMA_CHANNEL_INDEX eChannel
)
{
UINT32 u32SFR;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
outp32(u32SFR, inp32(u32SFR) & ~EDMASG_EN);
}
// Set Descript Format for Scatter Gather
// This function only support Order =0
ERRCODE
DrvEDMA_SetScatterGatherSetting(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32SGTblStartAddr,
S_DRVEDMA_DESCRIPT_SETTING* psDescript
)
{
UINT32 u32SFR, u32Value;
S_DRVEDMA_DESCRIPT_FORMAT *psSGFmt;
UINT32 u32TranferByte=0;
UINT32 u32TotalByteCount;
UINT32 u32NewSrcAddr, u32NewDestAddr, u32AddSrcAddr, u32AddDestAddr;
E_DRVEDMA_COLOR_FORMAT eSrcFormat, eDestFormat;
UINT32 u32MaxTxfBytePerTbl;
if ((int)psDescript->u32TransferByteCount <=0)
return E_DRVEDMA_FALSE_INPUT;
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
eSrcFormat = (inp32(u32SFR) & SOUR_FORMAT) >> 24;
eDestFormat = (inp32(u32SFR) & DEST_FORMAT) >> 16;
u32SFR = REG_VDMA_CSR + eChannel * 0x100;
u32Value = inp32(u32SFR);
u32Value = (u32Value & ~SAD_SEL) | (psDescript->eSrcDirection << SOURCE_DIRECTION_BIT);
u32Value = (u32Value & ~DAD_SEL) | (psDescript->eDestDirection << DESTINATION_DIRECTION_BIT);
outp32(u32SFR,u32Value);
DrvEDMA_EnableScatterGather(eChannel);
DrvEDMA_SetScatterGatherTblStartAddr(eChannel, u32SGTblStartAddr);
psSGFmt = (S_DRVEDMA_DESCRIPT_FORMAT *)u32SGTblStartAddr;
u32TotalByteCount = psDescript->u32TransferByteCount;
u32NewSrcAddr = psDescript->u32SourceAddr;
u32NewDestAddr = psDescript->u32DestAddr;
u32AddSrcAddr=0;
u32AddDestAddr=0;
// Update TransferByteCount for stride mode
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
if ((psDescript->u32Stride) && (inp32(u32SFR) & STRIDE_EN))
u32MaxTxfBytePerTbl = MAX_GS_TRANSFER_SIZE / psDescript->u32Stride * psDescript->u32Stride;
else
u32MaxTxfBytePerTbl = MAX_GS_TRANSFER_SIZE;
do {
// Set Phsyical Source Address and Destination Address
// Set WrapAround and Fixed Direction in Scatter Gather as Fixed Direction
if (psDescript->eSrcDirection == eDRVEDMA_DIRECTION_INCREMENTED)
{
psSGFmt->u32SourceAddr = u32NewSrcAddr + u32AddSrcAddr;
u32NewSrcAddr += u32AddSrcAddr;
}
else
{
if (psDescript->eSrcDirection == eDRVEDMA_DIRECTION_DECREMENTED)
{
psSGFmt->u32SourceAddr = u32NewSrcAddr - u32AddSrcAddr;
u32NewSrcAddr -= u32AddSrcAddr;
}
else
psSGFmt->u32SourceAddr = u32NewSrcAddr;
}
if (psDescript->eDestDirection == eDRVEDMA_DIRECTION_INCREMENTED)
{
psSGFmt->u32DestAddr = u32NewDestAddr + u32AddDestAddr;
u32NewDestAddr += u32AddDestAddr;
}
else
{
if (psDescript->eDestDirection == eDRVEDMA_DIRECTION_DECREMENTED)
{
psSGFmt->u32DestAddr = u32NewDestAddr - u32AddDestAddr;
u32NewDestAddr -= u32AddDestAddr;
}
else
psSGFmt->u32DestAddr = u32NewDestAddr;
}
if (u32TotalByteCount >= u32MaxTxfBytePerTbl)
{
u32TranferByte = u32MaxTxfBytePerTbl;
u32TotalByteCount -= u32MaxTxfBytePerTbl;
}
else
{
u32TranferByte = u32TotalByteCount;
u32TotalByteCount = 0;
}
// Src/Dest format must be set before DrvEDMA_SetScatterGatterSetting() function to calcuate the next address
u32SFR = REG_VDMA_CTCSR + eChannel * 0x100;
if ((psDescript->u32Stride) && (inp32(u32SFR) & STRIDE_EN) && (eChannel ==0))
{ // Calculate the next Src/Destination for Stride mode
u32AddSrcAddr = (u32TranferByte / psDescript->u32Stride) * (psDescript->u32SrcOffset + psDescript->u32Stride) +
u32TranferByte % psDescript->u32Stride;
if (eSrcFormat == eDRVEDMA_RGB888)
{
if (eDestFormat== eDRVEDMA_RGB888)
u32AddDestAddr = (u32TranferByte / psDescript->u32Stride) * (psDescript->u32DestOffset + psDescript->u32Stride) +
u32TranferByte % psDescript->u32Stride;
else
u32AddDestAddr = (u32TranferByte / psDescript->u32Stride) * (psDescript->u32DestOffset + psDescript->u32Stride/2) +
u32TranferByte % psDescript->u32Stride/2;
}
else
{
if (eDestFormat== eDRVEDMA_RGB888)
u32AddDestAddr = (u32TranferByte / psDescript->u32Stride) * (psDescript->u32DestOffset + psDescript->u32Stride*2) +
u32TranferByte % psDescript->u32Stride*2;
else
u32AddDestAddr = (u32TranferByte / psDescript->u32Stride) * (psDescript->u32DestOffset + psDescript->u32Stride) +
u32TranferByte % psDescript->u32Stride;
}
}
else
{ // Calculate the next Src/Destination for non-Stride mode
u32AddSrcAddr = u32TranferByte;
if (eChannel ==0)
{
if (eSrcFormat == eDRVEDMA_RGB888)
{
if (eDestFormat== eDRVEDMA_RGB888)
u32AddDestAddr = u32TranferByte;
else
u32AddDestAddr = u32TranferByte/2;
}
else
{
if (eDestFormat== eDRVEDMA_RGB888)
u32AddDestAddr = u32TranferByte*2;
else
u32AddDestAddr =u32TranferByte;
}
}
else
{
u32AddDestAddr = u32TranferByte;
}
}
// Set Stride Transfer Byte Count & Byte Count
psSGFmt->u32StrideAndByteCount = ((psDescript->u32Stride & 0x7FFF) << 17) | u32TranferByte;
// Set Source Offset Byte Length and Destination Offset Byte Length
psSGFmt->u32Offset = ((psDescript->u32DestOffset & 0x7FFF) << 16) |
(psDescript->u32SrcOffset & 0x7FFF);
// Set EOT for last Descript Format
if (u32TotalByteCount == 0)
psSGFmt->u32Offset |= 0x80000000;
// Set Next Scatter Gether Table Address
psSGFmt->u32NextSGTblAddr = (UINT32)(psSGFmt+1);
psSGFmt++;
} while(u32TotalByteCount > 0);
return E_SUCCESS;
}
DrvEDMA.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/****************************************************************
* *
* Copyright (c) Nuvoton Technology Corp. All rights reserved. *
* *
****************************************************************/
/****************************************************************
Total:
Revision History:
05/26/2009, first creation
****************************************************************/
#ifndef __DRVEDMA_H__
#define __DRVEDMA_H__
#include "wbio.h"
#include "w55fa93_reg.h"
#ifdef __cplusplus
extern "C"
{
#endif
#define E_SUCCESS 0
#define DESTINATION_DIRECTION_BIT 6
#define SOURCE_DIRECTION_BIT 4
#define TRANSFER_WIDTH_BIT 19
#define MODE_SELECT_BIT 2
#define MAX_TRANSFER_BYTE_COUNT 0x00FFFFFF
#define MAX_CHANNEL_NUM 4
#define ERRCODE UINT32
#define ERR_EDMA (0xFFFF0000 | ((EDMA_BA>>16) & 0xFF00) |((EDMA_BA>>8) & 0xFF))
#define E_DRVEDMA_FALSE_INPUT (ERR_EDMA | 00)
// For interrupt CallBack Function
typedef void (*PFN_DRVEDMA_CALLBACK)(UINT32);
/****************************************************************
Enumerate Type
****************************************************************/
typedef enum
{
eDRVEDMA_DISABLE =0,
eDRVEDMA_ENABLE
}E_DRVEDMA_OPERATION;
typedef enum
{
eDRVEDMA_CHANNEL_0 =0,
eDRVEDMA_CHANNEL_1,
eDRVEDMA_CHANNEL_2,
eDRVEDMA_CHANNEL_3,
eDRVEDMA_CHANNEL_4
}E_DRVEDMA_CHANNEL_INDEX;
typedef enum
{
eDRVEDMA_TARGET_SOURCE =0,
eDRVEDMA_TARGET_DESTINATION
}E_DRVEDMA_TARGET;
typedef enum
{
eDRVEDMA_WRAPAROUND_NO_INT =0,
eDRVEDMA_WRAPAROUND_EMPTY, // empty
eDRVEDMA_WRAPAROUND_THREE_FOURTHS, // 3/4
eDRVEDMA_WRAPAROUND_HALF=4, // 1/2
eDRVEDMA_WRAPAROUND_QUARTER=8 // 1/4
}E_DRVEDMA_WRAPAROUND_SELECT;
typedef enum
{
eDRVEDMA_TABORT_FLAG =1,
eDRVEDMA_BLKD_FLAG,
eDRVEDMA_SG_FLAG=8,
eDRVEDMA_WRA_EMPTY_FLAG=0x100, // empty
eDRVEDMA_WRA_THREE_FOURTHS_FLAG=0x200, // 3/4
eDRVEDMA_WRA_HALF_FLAG=0x400, // 1/2
eDRVEDMA_WRA_QUARTER_FLAG=0x800 // 1/4
}E_DRVEDMA_INT_FLAG;
typedef enum
{
eDRVEDMA_DIRECTION_INCREMENTED =0,
eDRVEDMA_DIRECTION_DECREMENTED,
eDRVEDMA_DIRECTION_FIXED,
eDRVEDMA_DIRECTION_WRAPAROUND
}E_DRVEDMA_DIRECTION_SELECT;
typedef enum
{
eDRVEDMA_WIDTH_32BITS=0,
eDRVEDMA_WIDTH_8BITS,
eDRVEDMA_WIDTH_16BITS
}E_DRVEDMA_TRANSFER_WIDTH;
typedef enum
{
eDRVEDMA_TABORT =1,
eDRVEDMA_BLKD,
eDRVEDMA_WAR=4,
eDRVEDMA_SG=8
}E_DRVEDMA_INT_ENABLE;
typedef enum
{
eDRVEDMA_RGB888=1,
eDRVEDMA_RGB555=2,
eDRVEDMA_RGB565=4,
eDRVEDMA_YCbCr422=8
}E_DRVEDMA_COLOR_FORMAT;
typedef enum
{
eDRVEDMA_SPIMS0=0,
eDRVEDMA_SPIMS1,
eDRVEDMA_UART0,
eDRVEDMA_UART1,
eDRVEDMA_ADC
}E_DRVEDMA_APB_DEVICE;
typedef enum
{
eDRVEDMA_READ_APB=0,
eDRVEDMA_WRITE_APB
}E_DRVEDMA_APB_RW;
typedef enum
{
eDRVEDMA_MEMORY_TO_MEMORY =0,
eDRVEDMA_DEVICE_TO_MEMORY,
eDRVEDMA_MEMORY_TO_DEVICE
}E_DRVEDMA_MODE_SELECT;
typedef struct {
UINT32 u32Addr;
E_DRVEDMA_DIRECTION_SELECT eAddrDirection;
}S_DRVEDMA_CH_ADDR_SETTING;
typedef struct {
UINT32 u32SourceAddr;
E_DRVEDMA_DIRECTION_SELECT eSrcDirection;
UINT32 u32DestAddr;
E_DRVEDMA_DIRECTION_SELECT eDestDirection;
UINT32 u32TransferByteCount;
UINT32 u32Stride;
UINT32 u32SrcOffset;
UINT32 u32DestOffset;
}S_DRVEDMA_DESCRIPT_SETTING;
typedef struct {
UINT32 u32SourceAddr;
UINT32 u32DestAddr;
UINT32 u32StrideAndByteCount;
UINT32 u32Offset;
UINT32 u32NextSGTblAddr;
}S_DRVEDMA_DESCRIPT_FORMAT;
/****************************************************************
// APIs declaration
****************************************************************/
UINT32
DrvEDMA_Open(void);
void DrvEDMA_Close(void);
BOOL
DrvEDMA_IsCHBusy(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
void DrvEDMA_EnableCH(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_OPERATION eOP
);
BOOL
DrvEDMA_IsEnabledCH(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
ERRCODE
DrvEDMA_SetTransferSetting(
E_DRVEDMA_CHANNEL_INDEX eChannel,
S_DRVEDMA_CH_ADDR_SETTING* psSrcAddr,
S_DRVEDMA_CH_ADDR_SETTING* psDestAddr,
UINT32 u32TransferLength
);
ERRCODE
DrvEDMA_GetTransferSetting(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_TARGET eTarget,
UINT32* pu32Addr,
E_DRVEDMA_DIRECTION_SELECT* peDirection
);
ERRCODE
DrvEDMA_GetTransferLength(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32* pu32TransferLength
);
ERRCODE
DrvEDMA_SetAPBTransferWidth(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_TRANSFER_WIDTH eTransferWidth
);
ERRCODE
DrvEDMA_GetAPBTransferWidth(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_TRANSFER_WIDTH* peTransferWidth
);
ERRCODE
DrvEDMA_SetCHForAPBDevice(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_APB_DEVICE eDevice,
E_DRVEDMA_APB_RW eRWAPB
);
E_DRVEDMA_CHANNEL_INDEX
DrvEDMA_GetCHForAPBDevice(
E_DRVEDMA_APB_DEVICE eDevice,
E_DRVEDMA_APB_RW eRWAPB
);
ERRCODE
DrvEDMA_SetWrapIntType(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_WRAPAROUND_SELECT eType
);
E_DRVEDMA_WRAPAROUND_SELECT
DrvEDMA_GetWrapIntType(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
ERRCODE
DrvEDMA_CHSoftwareReset(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
ERRCODE
DrvEDMA_CHEnablelTransfer(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
UINT32
DrvEDMA_GetCurrentSourceAddr(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
UINT32
DrvEDMA_GetCurrentDestAddr(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
UINT32
DrvEDMA_GetCurrentTransferCount(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
ERRCODE
DrvEDMA_EnableInt(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_ENABLE eIntSource
);
void DrvEDMA_DisableInt(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_ENABLE eIntSource
);
UINT32
DrvEDMA_IsIntEnabled(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_ENABLE eIntSource
);
void DrvEDMA_ClearInt(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_FLAG eIntFlag
);
BOOL
DrvEDMA_PollInt(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_FLAG eIntFlag
);
ERRCODE
DrvEDMA_SetColorTransformFormat(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_COLOR_FORMAT u32SourceFormat,
E_DRVEDMA_COLOR_FORMAT u32DestFormat
);
void DrvEDMA_GetColorTransformFormat(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_COLOR_FORMAT* pu32SourceFormat,
E_DRVEDMA_COLOR_FORMAT* pu32DestFormat
);
ERRCODE
DrvEDMA_SetColorTransformOperation(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_OPERATION eColorSpaceTran,
E_DRVEDMA_OPERATION eStrideMode
);
void DrvEDMA_GetColorTransformOperation(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_OPERATION* peColorSpaceTran,
E_DRVEDMA_OPERATION* peStrideMode
);
ERRCODE
DrvEDMA_SetSourceStride(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32StrideByteCount,
UINT32 u32OffsetByteLength
);
void DrvEDMA_GetSourceStride(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32* pu32StrideByteCount,
UINT32* pu32OffsetByteLength
);
ERRCODE
DrvEDMA_SetDestinationStrideOffset(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32OffsetByteLength
);
void DrvEDMA_GetDestinationStrideOffset(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32* pu32OffsetByteLength
);
ERRCODE
DrvEDMA_SetClamping(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_OPERATION eOP
);
E_DRVEDMA_OPERATION
DrvEDMA_GetClamping(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
UINT32
DrvEDMA_GetInternalBufPointer(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
UINT32
DrvEDMA_GetSharedBufData(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32BufIndex
);
ERRCODE
DrvEDMA_InstallCallBack(
E_DRVEDMA_CHANNEL_INDEX eChannel,
E_DRVEDMA_INT_ENABLE eIntSource,
PFN_DRVEDMA_CALLBACK pfncallback,
PFN_DRVEDMA_CALLBACK *pfnOldcallback
);
void DrvEDMA_GetScatterGatherInfo(
UINT32 *pu32TblSize,
UINT32 *pu32MaxTransferBytePerTbl
);
ERRCODE
DrvEDMA_SetScatterGatherSetting(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32SGTblStartAddr,
S_DRVEDMA_DESCRIPT_SETTING* psDescript
);
void DrvEDMA_EnableScatterGather(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
void DrvEDMA_DisableScatterGather(
E_DRVEDMA_CHANNEL_INDEX eChannel
);
void DrvEDMA_SetScatterGatherTblStartAddr(
E_DRVEDMA_CHANNEL_INDEX eChannel,
UINT32 u32TblStartAddr
);
UINT32
DrvEDMA_GetVersion(void);
#ifdef __cplusplus
}
#endif
#endif // __DRVEDMA_H__
fmi.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/*-----------------------------------------------------------------------------------*/
/* Nuvoton Technology Corporation confidential */
/* */
/* Copyright (c) 2008 by Nuvoton Technology Corporation */
/* All rights reserved */
/* */
/*-----------------------------------------------------------------------------------*/
#ifdef ECOS
#include "drv_api.h"
#include "diag.h"
#include "Common.h"
#include "wbio.h"
#define IRQ_SD 16
#else
#define IRQ_SD IRQ_SIC
#include "wblib.h"
#endif
#include "w55fa93_reg.h"
#include "w55fa93_sic.h"
#include "fmi.h"
//#include "nvtfat.h"
#ifdef ECOS
cyg_interrupt /* dmac_interrupt, */ fmi_interrupt;
cyg_handle_t /* dmac_interrupt_handle, */ fmi_interrupt_handle;
#endif
// global variable
//UINT32 _fmi_uFMIReferenceClock;
BOOL volatile _fmi_bIsSDDataReady=FALSE, _fmi_bIsSMDataReady=FALSE;
typedef void (*fmi_pvFunPtr)(); /* function pointer */
void (*fmiSD0RemoveFun)() = NULL;
void (*fmiSD0InsertFun)() = NULL;
extern PDISK_T *pDisk_SD0;
extern PDISK_T *pDisk_SD1;
extern PDISK_T *pDisk_SD2;
#ifdef _SIC_USE_INT_
#ifdef ECOS
static cyg_uint32 fmiIntHandler(cyg_vector_t vector, cyg_addrword_t data)
#else
VOID fmiIntHandler()
#endif
{
unsigned int volatile isr;
// FMI data abort interrupt
if (inpw(REG_FMIISR) & FMI_DAT_IF)
{
/* fmiResetAllEngine() */
outpw(REG_FMICR, inpw(REG_FMICR) | FMI_SWRST);
outpw(REG_FMIISR, FMI_DAT_IF);
}
// SD interrupt status
isr = inpw(REG_SDISR);
if (isr & SDISR_BLKD_IF) // block down
{
_fmi_bIsSDDataReady = TRUE;
outpw(REG_SDISR, SDISR_BLKD_IF);
}
if (isr & SDISR_CD_IF) // port 0 card detect
{
if (inpw(REG_SDISR) & SDISR_CD_Card)
{
pSD0->bIsCardInsert = FALSE;
if (fmiSD0RemoveFun != NULL)
(*fmiSD0RemoveFun)(pDisk_SD0);
}
else
{
pSD0->bIsCardInsert = TRUE;
if (fmiSD0InsertFun != NULL)
(*fmiSD0InsertFun)();
}
outpw(REG_SDISR, SDISR_CD_IF);
}
// SM interrupt status
isr = inpw(REG_SMISR);
if (isr & SMISR_DMA_IF)
{
_fmi_bIsSMDataReady = TRUE;
outpw(REG_SMISR, SMISR_DMA_IF);
}
#ifdef ECOS
cyg_drv_interrupt_acknowledge(IRQ_SD);
return CYG_ISR_HANDLED;
#endif
}
#endif //_SIC_USE_INT_
VOID fmiSetCallBack(UINT32 uCard, PVOID pvRemove, PVOID pvInsert)
{
switch (uCard)
{
case FMI_SD_CARD:
fmiSD0RemoveFun = (fmi_pvFunPtr)pvRemove;
fmiSD0InsertFun = (fmi_pvFunPtr)pvInsert;
break;
}
}
VOID fmiInitDevice()
{
// Enable SD Card Host Controller operation and driving clock.
outpw(REG_AHBCLK, inpw(REG_AHBCLK) | HCLK3_CKE | SIC_CKE | SD_CKE | NAND_CKE);
#ifdef _SIC_USE_INT_
/* Install ISR */
#ifdef ECOS
cyg_drv_interrupt_create(IRQ_SD, 10, 0, fmiIntHandler, NULL,
&fmi_interrupt_handle, &fmi_interrupt);
cyg_drv_interrupt_attach(fmi_interrupt_handle);
#else
sysInstallISR(IRQ_LEVEL_1, IRQ_SD, (PVOID)fmiIntHandler);
#endif
#ifndef ECOS
/* enable CPSR I bit */
sysSetLocalInterrupt(ENABLE_IRQ);
#endif
#endif //_SIC_USE_INT_
// DMAC Initial
outpw(REG_DMACCSR, DMAC_SWRST | DMAC_EN);
outpw(REG_DMACCSR, DMAC_EN);
#ifdef _SIC_USE_INT_
#ifdef ECOS
cyg_drv_interrupt_unmask(IRQ_SD);
#else
sysEnableInterrupt(IRQ_SD);
#endif
#endif //_SIC_USE_INT_
outpw(REG_FMICR, FMI_SWRST); // reset FMI engine
while(inpw(REG_FMICR)&FMI_SWRST);
}
VOID fmiSetFMIReferenceClock(UINT32 uClock)
{
_fmi_uFMIReferenceClock = uClock; // kHz
}
fmi.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef _FMI_H
#define _FMI_H
#include <stdio.h>
#include "wbio.h"
// define DATE FMI_DATE_CODE and show it when running to make maintaining easy.
#define FMI_DATE_CODE "20161207"
//#define _SIC_USE_INT_
//#define DEBUG
#define TIMER0 0
#define printf sysprintf
//#define _USE_DAT3_DETECT_
//-- function return value
#define Successful 0
#define Fail 1
//--- define type of SD card or MMC
#define FMI_TYPE_UNKNOWN 0
#define FMI_TYPE_SD_HIGH 1
#define FMI_TYPE_SD_LOW 2
#define FMI_TYPE_MMC 3 // MMC access mode: Byte mode for capacity <= 2GB
#define FMI_TYPE_MMC_SECTOR_MODE 4 // MMC access mode: Sector mode for capacity > 2GB
#ifdef ECOS
#define sysGetTicks(TIMER0) cyg_current_time()
//#define printf diag_printf
#endif
// extern global variables
extern UINT32 _fmi_uFMIReferenceClock;
extern BOOL volatile _fmi_bIsSDDataReady;
#define STOR_STRING_LEN 32
/* we allocate one of these for every device that we remember */
typedef struct disk_data_t
{
struct disk_data_t *next; /* next device */
/* information about the device -- always good */
unsigned int totalSectorN;
unsigned int diskSize; /* disk size in Kbytes */
int sectorSize;
char vendor[STOR_STRING_LEN];
char product[STOR_STRING_LEN];
char serial[STOR_STRING_LEN];
} DISK_DATA_T;
// function declaration
// SD functions
INT fmiSDCommand(FMI_SD_INFO_T *pSD, UINT8 ucCmd, UINT32 uArg);
INT fmiSDCmdAndRsp(FMI_SD_INFO_T *pSD, UINT8 ucCmd, UINT32 uArg, INT nCount);
INT fmiSDCmdAndRsp2(FMI_SD_INFO_T *pSD, UINT8 ucCmd, UINT32 uArg, UINT *puR2ptr);
INT fmiSDCmdAndRspDataIn(FMI_SD_INFO_T *pSD, UINT8 ucCmd, UINT32 uArg);
INT fmiSD_Init(FMI_SD_INFO_T *pSD);
INT fmiSelectCard(FMI_SD_INFO_T *pSD);
VOID fmiGet_SD_info(FMI_SD_INFO_T *pSD, DISK_DATA_T *_info);
INT fmiSD_Read_in(FMI_SD_INFO_T *pSD, UINT32 uSector, UINT32 uBufcnt, UINT32 uDAddr);
INT fmiSD_Write_in(FMI_SD_INFO_T *pSD, UINT32 uSector, UINT32 uBufcnt, UINT32 uSAddr);
INT fmiSD_CardStatus(void);
#endif // end of _FMI_H
hwsetup.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
//*----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name : HwSetup.c
//* Object : Low level initialisations written in C
//* Creation : FB 23/10/2002
//* Modify : SBb 10/06/2005
//*
//*----------------------------------------------------------------------------
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define HWSETUP_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
//*----------------------------------------------------------------------------
//* \fn EnableMainOscillator
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
VOID EnableMainOscillator(VOID)
{
}
//*----------------------------------------------------------------------------
//* \fn WaitForMainClockFrequency
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
BOOL WaitForMainClockFrequency(VOID)
{
return TRUE;
}
//*----------------------------------------------------------------------------
//* \fn InitClocks
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
VOID InitClocks(VOID)
{
}
VOID InitPIO(VOID)
{
outpw(REG_GPDFUN , inpw(REG_GPDFUN) &~ (0xFF0003FF));
outpw(REG_GPDFUN , inpw(REG_GPDFUN)|(0xFF000000));
//RF_RST
gpio_configure(GPIO_PORTB,5);//B5
gpio_setportdir(GPIO_PORTB, BIT5, BIT5);//Êä³ö
gpio_setportval(GPIO_PORTB, BIT5, BIT5);//Êä³ö0
//³õʼ»¯´òÓ¡Í·Òý½Å
outpw(REG_GPBFUN , inpw(REG_GPBFUN) &(~BIT19) | BIT18); //B9 spi_clk---TPH_CLK
outpw(REG_GPBFUN , inpw(REG_GPBFUN) &(~BIT25) | BIT24); //B12 spi_do---TPH_DAT
outpw(REG_GPBFUN , inpw(REG_GPBFUN) &(~BIT21) | BIT20); //B10 cs0
gpio_setportdir(GPIO_PORTB, BIT9|BIT10|BIT12, BIT9|BIT10|BIT12);//Êä³ö
gpio_setportval(GPIO_PORTB, BIT9|BIT10|BIT12, BIT9|BIT10|BIT12);//Êä³ö1
#if 1
//FLASH SPI
outpw(REG_GPDFUN , inpw(REG_GPDFUN) | BIT25 | BIT24); //D12 spi_clk
outpw(REG_GPDFUN , inpw(REG_GPDFUN) | BIT31 | BIT30); //D15 spi_do
outpw(REG_GPDFUN , inpw(REG_GPDFUN) | BIT27 | BIT26);//D13 cs0
gpio_setportdir(GPIO_PORTD, BIT12|BIT13|BIT15, BIT12|BIT13|BIT15);//Êä³ö
gpio_setportval(GPIO_PORTD, BIT12|BIT13|BIT15, BIT12|BIT13|BIT15);//Êä³ö1
#endif
//Ëø´æÒý½Å
gpio_configure(GPIO_PORTB,10); //B10---TPH_LTACH
gpio_setportdir(GPIO_PORTB, BIT10, BIT10);//Êä³ö
gpio_setportval(GPIO_PORTB, BIT10, BIT10);//Êä³ö1
//TPH_POWER
gpio_configure(GPIO_PORTB,11);//B11
gpio_setportdir(GPIO_PORTB, BIT11, BIT11);
gpio_setportval(GPIO_PORTB, BIT11, 0);
//STB2
gpio_configure(GPIO_PORTB,7);//B7
gpio_setportdir(GPIO_PORTB, BIT7, BIT7);
gpio_setportval(GPIO_PORTB, BIT7, BIT7);
gpio_setportpull(GPIO_PORTB, BIT7, BIT7);
//STB1
gpio_configure(GPIO_PORTB,8);//B8
gpio_setportdir(GPIO_PORTB, BIT8, BIT8);
gpio_setportval(GPIO_PORTB, BIT8, BIT8);
gpio_setportpull(GPIO_PORTB, BIT8, BIT8);
//adc sw IO
gpio_configure(GPIO_PORTA,5); //A5_ADC_SW01
gpio_configure(GPIO_PORTA,6); //A6_ADC_SW02
gpio_setportdir(GPIO_PORTA, BIT5|BIT6, BIT5|BIT6);//OUT PUT
gpio_setportval(GPIO_PORTA, BIT5|BIT6, 0);//OUT 0
//cutter
gpio_configure(GPIO_PORTE,1); //CUT_EN-->E1
gpio_configure(GPIO_PORTE,0); //CUT_PH-->E0
gpio_setportdir(GPIO_PORTE, BIT1|BIT0, BIT1|BIT0);
gpio_configure(GPIO_PORTC,15);//CUT_SENSOR --> C15
gpio_setportdir(GPIO_PORTC, BIT15, 0);
//set sensor intension control IO
gpio_configure(GPIO_PORTD,8);//GAP0 --> D8
gpio_setportdir(GPIO_PORTD, BIT8, BIT8);
gpio_configure(GPIO_PORTD,7);//GAP1 --> D7
gpio_setportdir(GPIO_PORTD, BIT7, BIT7);
gpio_configure(GPIO_PORTE,11);//GAP2 --> E11
gpio_setportdir(GPIO_PORTE, BIT11, BIT11);
gpio_configure(GPIO_PORTE,10);//GAP4 --> E10
gpio_setportdir(GPIO_PORTE, BIT10, BIT10);
gpio_configure(GPIO_PORTD,5);//BLINE0 --> D5
gpio_setportdir(GPIO_PORTD, BIT5, BIT5);
gpio_configure(GPIO_PORTD,6);//BLINE1 --> D6
gpio_setportdir(GPIO_PORTD, BIT6, BIT6);
//KEY
gpio_configure(GPIO_PORTC,12);// KEY_1 -> C12
gpio_setportdir(GPIO_PORTC, BIT12, 0); // input
// gpio_configure(GPIO_PORTC,11);// KEY_2 ->C11 // ch_20220120
// gpio_setportdir(GPIO_PORTC, BIT11, 0); // input // ch_20220120
// gpio_configure(GPIO_PORTC,10);// KEY_3 ->C10
// gpio_setportdir(GPIO_PORTC, BIT10, 0); // input
// gpio_configure(GPIO_PORTC,9);// KEY_4 ->C9
// gpio_setportdir(GPIO_PORTC, BIT9, 0); // input
// gpio_configure(GPIO_PORTC,8);// KEY_5 ->C8 // ch_20220120
// gpio_setportdir(GPIO_PORTC, BIT8, 0); // input // ch_20220120
//led
gpio_configure(GPIO_PORTC,13); // LED_GREEN -> C13
gpio_setportdir(GPIO_PORTC, BIT13, 0/*BIT13*/); // ch_20211221
gpio_configure(GPIO_PORTC,14); //LED_RED -> C14
gpio_setportdir(GPIO_PORTC, BIT14, 0/*BIT14*/); // ch_20211221
//Carriage
gpio_configure(GPIO_PORTE,8);// HEAD -> E8
gpio_setportdir(GPIO_PORTE, BIT8, 0);
gpio_setportpull(GPIO_PORTE, BIT8, BIT8);
//setp motor
#if ORIGIN_STEP_MOTOR_DRIVE
gpio_configure(GPIO_PORTA,2);//PH1 -> A2
gpio_setportdir(GPIO_PORTA,BIT2, BIT2);
gpio_setportpull(GPIO_PORTA, BIT2, BIT2); // ch_20220127
gpio_setportval(GPIO_PORTA,BIT2,BIT2);
gpio_configure(GPIO_PORTA,4);//PH2 -> A4
gpio_setportdir(GPIO_PORTA,BIT4,BIT4);
gpio_setportpull(GPIO_PORTA, BIT4, BIT4); // ch_20220127
gpio_setportval(GPIO_PORTA,BIT4,BIT4);
#endif
gpio_configure(GPIO_PORTA,3);//MD_EN -> A3
gpio_setportdir(GPIO_PORTA,BIT3,BIT3);
gpio_setportval(GPIO_PORTA,BIT3,0);
#if NEW_STEP_MOTOR_DRIVE
// ch_20220120
// gpio_configure(GPIO_PORTC, 7);
// gpio_configure(GPIO_PORTC, 8);
// gpio_setportdir(GPIO_PORTC, BIT8|BIT7, BIT8|BIT7); // drive Step motor.
// gpio_setportpull(GPIO_PORTC, BIT8, BIT8); // ch_20220127
// gpio_setportval(GPIO_PORTC, BIT7, 0);
// gpio_setportval(GPIO_PORTC, BIT8, BIT8);
// gpio_configure(GPIO_PORTC, 10);
// gpio_configure(GPIO_PORTC, 11);
// gpio_setportdir(GPIO_PORTC, BIT11|BIT10, BIT11|BIT10); // drive Step motor.
// gpio_setportpull(GPIO_PORTC, BIT11, BIT11); // ch_20220127
// gpio_setportval(GPIO_PORTC, BIT10, 0);
// gpio_setportval(GPIO_PORTC, BIT11, BIT11);
gpio_configure(GPIO_PORTC, 0); // ch_20220130
gpio_configure(GPIO_PORTC, 3); // ch_20220130
gpio_configure(GPIO_PORTC, 6);
gpio_configure(GPIO_PORTC, 8);
gpio_configure(GPIO_PORTC, 9);
gpio_configure(GPIO_PORTC, 11);
gpio_setportdir(GPIO_PORTC, BIT11|BIT9|BIT8|BIT6|BIT3|BIT0, BIT11|BIT9|BIT8|BIT6|BIT3|BIT0); // drive Step motor.
#if FULL_STEP_FULL_CURRENT
gpio_setportpull(GPIO_PORTC, BIT11|BIT8, BIT11|BIT8); // ch_20220127
gpio_setportval(GPIO_PORTC, BIT11|BIT8, BIT11|BIT8);
gpio_setportval(GPIO_PORTC, BIT9|BIT6|BIT3|BIT0, ~(BIT9|BIT6|BIT3|BIT0));
#elif HALF_STEP_FULL_CURRENT
gpio_setportpull(GPIO_PORTC, BIT11|BIT9|BIT8|BIT6, BIT11|BIT9|BIT8|BIT6); // ch_20220127
gpio_setportval(GPIO_PORTC, BIT11|BIT9|BIT8|BIT6, BIT11|BIT9|BIT8|BIT6);
gpio_setportval(GPIO_PORTC, BIT3|BIT0, ~(BIT3|BIT0));
#elif HALF_STEP_PART_CURRENT
gpio_setportpull(GPIO_PORTC, BIT11|BIT9|BIT8|BIT6|BIT3|BIT0, BIT11|BIT9|BIT8|BIT6|BIT3|BIT0); // ch_20220127
gpio_setportval(GPIO_PORTC, BIT11|BIT9|BIT8|BIT6|BIT3|BIT0, BIT11|BIT9|BIT8|BIT6|BIT3|BIT0);
#endif
#endif
//DC motor
gpio_configure(GPIO_PORTA,0);//DC_MOTOR_PHASE -> A0
gpio_setportdir(GPIO_PORTA,BIT0,BIT0);
gpio_setportval(GPIO_PORTA,BIT0,0);
gpio_configure(GPIO_PORTD,0);//DC_MOTOR_PWM -> D0
gpio_setportdir(GPIO_PORTD,BIT0,BIT0);
gpio_setportval(GPIO_PORTD,BIT0,0);
gpio_configure(GPIO_PORTE,9);//RIBBON_SENSER --> E9
gpio_setportdir(GPIO_PORTE, BIT9, 0);
//PEEL
gpio_configure(GPIO_PORTB,4);//PEEL_EN -> B4
gpio_setportdir(GPIO_PORTB, BIT4, BIT4);
gpio_setportpull(GPIO_PORTB, BIT4, BIT4);
gpio_configure(GPIO_PORTB,3);//PEEL_SW -> B4
gpio_setportdir(GPIO_PORTB, BIT3, BIT3);
gpio_setportpull(GPIO_PORTB, BIT3, BIT3);
//power down
gpio_configure(GPIO_PORTB,2);//power down -> B2
gpio_setportdir(GPIO_PORTB, BIT2, 0);
gpio_setportpull(GPIO_PORTB, BIT2, 0);
//I2C_SDA
gpio_configure(GPIO_PORTB,14);//B14
gpio_setportdir(GPIO_PORTB, BIT14, BIT14);
gpio_setportval(GPIO_PORTB, BIT14, BIT14);
gpio_setportpull(GPIO_PORTB, BIT14, BIT14);
//I2C_SCL
gpio_configure(GPIO_PORTB,13);//B13
gpio_setportdir(GPIO_PORTB, BIT13, BIT13);
gpio_setportval(GPIO_PORTB, BIT13, BIT13);
gpio_setportpull(GPIO_PORTB, BIT13, BIT13);
//SD DET
gpio_configure(GPIO_PORTA,1);//A1
gpio_setportdir(GPIO_PORTA, BIT1, 0);
//HUART
outpw(REG_GPDFUN, inpw(REG_GPDFUN) & (~BIT3)| BIT2);// HUR_TX-> D1
outpw(REG_GPDFUN, inpw(REG_GPDFUN) & (~BIT5)| BIT4);// HUR_RX-> D2
//gpio_configure(GPIO_PORTA,7);// HUR_RTS-> A7
//gpio_setportdir(GPIO_PORTA, BIT7, BIT7);// RTS->OUT PUT
//gpio_configure(GPIO_PORTD,4);// HUR_CTS-> D3
//gpio_setportdir(GPIO_PORTD, BIT4, 0);// CTS->IN PUT
//UART
outpw(REG_GPAFUN, inpw(REG_GPAFUN) | BIT21 | BIT20);//UART_TX -> A10
outpw(REG_GPAFUN, inpw(REG_GPAFUN) | BIT23 | BIT22);//UART_RX -> A11
//gpio_configure(GPIO_PORTB,5);// UART_RTS-> B5
//gpio_setportdir(GPIO_PORTB, BIT5, BIT5);// RTS->OUT PUT
//gpio_configure(GPIO_PORTB,6);// UART_CTS-> B6
//gpio_setportdir(GPIO_PORTB, BIT6, 0);// CTS->IN PUT
}
//*----------------------------------------------------------------------------
//* \fn LowLevelInit
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
INT __low_level_init(VOID)
{
InitPIO();
/*==================================*/
/* Choose if segment initialization */
/* should be done or not. */
/* Return: 0 to omit seg_init */
/* 1 to run seg_init */
/*==================================*/
return (1);
}
hwsetup.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
//*----------------------------------------------------------------------------
//* ATMEL Microcontroller Software Support - ROUSSET -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name : init.h
//* Object : Low level initialisations written in C
//* Create : SBb 10/06/2005
//*
//*----------------------------------------------------------------------------
#ifndef HWSETUP_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define HWSETUP_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
libadc.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/****************************************************************************
* *
* Copyright (c) 2009 Nuvoton Tech. Corp. All rights reserved. *
* *
*****************************************************************************/
/****************************************************************************
* FILENAME
* libadc.c
*
* VERSION
* 1.0
*
* DESCRIPTION
* ADC touch screen library source file
*
* DATA STRUCTURES
* None
*
* FUNCTIONS
*
* HISTORY
*
* REMARK
* None
****************************************************************************/
#include "W55fa93_adc.h"
#include "W55fa93_reg.h"
/* Verbose debug information */
#define DBG_PRINTF(...) //sysprintf
#define SORT_FIFO 6
/* Define the operation state machine */
#define E_ADC_UNINIT 0
#define E_ADC_INIT 1
#define E_ADC_OPEN 2
#define ADC_STATE_WT 0 // waiting for trigger mode
#define ADC_STATE_AUTO 1 // auto
static unsigned char _opened = E_ADC_UNINIT;
// These two will always store the latest sampled value
static unsigned short _hr, _vr;
static unsigned char volatile _state;
static INT32 i32_x=0, i32_y=0;
typedef enum{
eADC_BAND_P0P5 = 0,
eADC_BAND_P0P75
}E_ADC_UPBAND;
typedef enum{
eADC_BAND_N0P5 = 0,
eADC_BAND_N0P75
}E_ADC_DOWNBAND;
typedef enum{
eADC_PRE_P0 = 0,
eADC_PRE_P8,
eADC_PRE_P14,
eADC_PRE_P20
}E_ADC_PREGAIN;
typedef enum{
eADC_NG_N30 = 0,
eADC_NG_N36,
eADC_NG_N42,
eADC_NG_N48
}E_ADC_NOISEGATE;
typedef enum{
eADC_POST_N12 = 0,
eADC_POST_N11P25,
eADC_POST_N10P5,
eADC_POST_N9P75,
eADC_POST_N9,
eADC_POST_N8P25,
eADC_POST_N7P5,
eADC_POST_N6P75,
eADC_POST_N6,
eADC_POST_N5P25,
eADC_POST_N4P5,
eADC_POST_N3P75,
eADC_POST_N3,
eADC_POST_N2P25,
eADC_POST_N1P5,
eADC_POST_N0P75,
eADC_POST_P0,
eADC_POST_P0P75,
eADC_POST_P1P5,
eADC_POST_P2P25,
eADC_POST_P3,
eADC_POST_P3P75,
eADC_POST_P4P5,
eADC_POST_P5P25,
eADC_POST_P6,
eADC_POST_P6P75,
eADC_POST_P7P5,
eADC_POST_P8P25,
eADC_POST_P9,
eADC_POST_P9P75,
eADC_POST_P10P5,
eADC_POST_P11P25,
eADC_POST_P12,
eADC_POST_P12P75,
eADC_POST_P13P5,
eADC_POST_P14P25,
eADC_POST_P15,
eADC_POST_P15P75,
eADC_POST_P16P5,
eADC_POST_P17P25,
eADC_POST_P18,
eADC_POST_P18P75,
eADC_POST_P19P5,
eADC_POST_P20P25,
eADC_POST_P21,
eADC_POST_P21P75,
eADC_POST_P22P5,
eADC_POST_P23P25,
eADC_POST_P24,
eADC_POST_P24P75,
eADC_POST_P25P5,
eADC_POST_P26P25,
eADC_POST_P27,
eADC_POST_P27P75,
eADC_POST_P28P5,
eADC_POST_P29P25,
eADC_POST_P30,
eADC_POST_P30P75,
eADC_POST_P31P5,
eADC_POST_P32P25,
eADC_POST_P33,
eADC_POST_P33P75,
eADC_POST_P34P5,
eADC_POST_P35P25
}E_ADC_POSTGAIN;
typedef enum{
eADC_TSCREEN_4WIRE = 0,
eADC_TSCREEN_5WIRE, /* FA93 reserved for the item*/
eADC_TSCREEN_8WIRE, /* FA93 reserved for the item*/
eADC_TSCREEN_UNUSED /* FA93 reserved for the item*/
}E_ADC_TSC_TYPE;
typedef void (*PFN_ADC_CALLBACK)(VOID);
static PFN_ADC_CALLBACK g_psADCCallBack[4]={0, 0, 0, 0};
static __inline VOID DrvADC_PollingADC(VOID)
{
while( (inp32(REG_ADC_CON) & ADC_INT) != ADC_INT); /* Wait until ADC INT */
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & /* Clean the ADC interrupt */
~(WT_INT | LVD_INT)) |
(WT_INT |ADC_INT));
}
static __inline VOID DrvADC_PollingWT(VOID)
{
while( (inp32(REG_ADC_CON) & WT_INT) != WT_INT); /* Wait until ADC INT */
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & /* Clean the touch panel interrupt */
~WT_INT) );
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & /* Clean the touch panel interrupt */
~(LVD_INT | ADC_INT)) |
(WT_INT |ADC_INT));
}
static __inline BOOL DrvADC_IsPenDown(VOID)
{
if ( (inp32(REG_ADC_TSC) & ADC_UD) == ADC_UD)
return TRUE; //Pen down;
else
return FALSE; //Pen up;
}
/* =============================== sorting =============================== */
void swap(UINT16 *x,UINT16 *y)
{
UINT16 temp;
temp = *x;
*x = *y;
*y = temp;
}
UINT16 choose_pivot(UINT16 i,UINT16 j )
{
return((i+j) /2);
}
void quicksort(UINT16 list[],int m,int n)
{
int key,i,j,k;
if( m < n)
{
k = choose_pivot(m,n);
swap(&list[m],&list[k]);
key = list[m];
i = m+1;
j = n;
while(i <= j)
{
while((i <= n) && (list[i] <= key))
i++;
while((j >= m) && (list[j] > key))
j--;
if( i < j)
swap(&list[i],&list[j]);
}
// swap two elements
swap(&list[m],&list[j]);
// recursively sort the lesser list
quicksort(list,m,j-1);
quicksort(list,j+1,n);
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* DrvADC_EnableInt() */
/* */
/* DESCRIPTION */
/* enable ADC interrupt and setup callback function */
/* */
/* INPUTS */
/* callback */
/* The callback funciton */
/* */
/* u32UserData */
/* The user's data to pass to the callback function */
/* */
/* OUTPUTS */
/* none */
/* */
/* RETURN */
/* none */
/* */
/*---------------------------------------------------------------------------------------------------------*/
UINT32
adc_enableInt(
E_ADC_INT eIntType
)
{
/* Enable adc interrupt */
#ifdef USING_INT
switch(eIntType)
{
case eADC_ADC_INT:
outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_INT_EN);
break;
case eADC_AUD_INT:
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) | AUDIO_INT_EN);
break;
case eADC_LVD_INT:
outp32(REG_ADC_CON, inp32(REG_ADC_CON) | LVD_INT_EN);
break;
case eADC_WT_INT:
outp32(REG_ADC_CON, inp32(REG_ADC_CON) | WT_INT_EN);
break;
default:
return -1;
}
#endif
return Successful;
}
UINT32 adc_disableInt(E_ADC_INT eIntType)
{
/* Enable adc interrupt */
switch(eIntType)
{
case eADC_ADC_INT:
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & ~ADC_INT_EN);
break;
case eADC_AUD_INT:
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) & ~AUDIO_INT_EN);
break;
case eADC_LVD_INT:
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & ~LVD_INT_EN);
break;
case eADC_WT_INT:
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & ~WT_INT_EN);
break;
default:
return -1;//E_DRVADC_INVALID_INT;
}
return Successful;
}
/*---------------------------------------------------------------------------------------------------------*/
/* */
/* FUNCTION */
/* DrvADC_SetTouchScreen() */
/* */
/* DESCRIPTION */
/* Set the parameter for TSC */
/* */
/* INPUTS */
/* eTscMode Normal mode, Semi-Auto, Auto or Wait for trigger */
/* eTscWire 4 wire, 5 wire, 8 wire or unused */
/* bIsPullup Control the internal pull up PMOS in switch box */
/* bMAVFilter Enable or disable MAV filter in TSC auto mode */
/* OUTPUTS */
/* none */
/* */
/* RETURN */
/* none */
/* */
/*---------------------------------------------------------------------------------------------------------*/
void adc_setTouchScreen(
E_ADC_TSC_MODE eTscMode,
UINT32 u32DleayCycle,
BOOL bIsPullup,
BOOL bMAVFilter
)
{
//Change mode should reset ADC IP. otherwise, the ADC will hang-up
outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
if(eTscMode==eADC_TSCREEN_AUTO)
_state = ADC_STATE_AUTO;
else if(eTscMode==eADC_TSCREEN_TRIG)
_state = ADC_STATE_WT;
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & ~ADC_CON_ADC_EN);//打开ADC
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & ~(ADC_TSC_MODE | ADC_MUX)) |
(eTscMode << 14) );//设置模式
outp32(REG_ADC_DLY, u32DleayCycle);
outp32(REG_ADC_TSC, (inp32(REG_ADC_TSC) & ~(ADC_TSC_TYPE | ADC_PU_EN | ADC_TSC_MAV_EN)) |
( (((eADC_TSCREEN_4WIRE << 1) & ADC_TSC_TYPE) | ((bIsPullup <<3) & ADC_PU_EN)) |
((bMAVFilter<<9) & ADC_TSC_MAV_EN) ));
outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CON_ADC_EN);
}
void DrvADC_Conversion(void)
{
outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CONV);
}
void DrvADC_GetNormalData(PUINT16 pu16Data)
{
*pu16Data = inp32(REG_ADC_XDATA);
}
void DrvADC_GetTscData(
PUINT16 pu16XData,
PUINT16 pu16YData
)
{
*pu16XData = inp32(REG_ADC_XDATA);
*pu16YData = inp32(REG_ADC_YDATA);
}
static BOOL g_bIsADCInt =FALSE;
static BOOL g_bIsWTInt =FALSE;
static BOOL g_bIsAudioInt =FALSE;
static void adc_isr(void)
{
UINT32 u32Reg;
u32Reg = inp32(REG_ADC_CON);
/* Process ADC interrupt */
if( (u32Reg & (ADC_INT_EN | ADC_INT)) == (ADC_INT_EN | ADC_INT))
{//ADC interrupt
if(g_psADCCallBack[eADC_ADC_INT]!=0)
g_psADCCallBack[eADC_ADC_INT]();
g_bIsADCInt = TRUE;
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & /* Clean the ADC interrupt */
~(WT_INT | LVD_INT)) |
(WT_INT |ADC_INT));
return;
}
if( (u32Reg & (LVD_INT_EN | LVD_INT)) == (LVD_INT_EN | LVD_INT))
{//LVD interrupt
if(g_psADCCallBack[eADC_LVD_INT]!=0)
g_psADCCallBack[eADC_LVD_INT]();
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & /* Clean the LVD interrupt */
~(WT_INT | ADC_INT)) |
LVD_INT);
return;
}
if( (u32Reg & (WT_INT_EN | WT_INT)) == (WT_INT_EN | WT_INT))
{//Wait for trigger
/*Disable WT int */
if((inp32(REG_ADC_CON) & ADC_TSC_MODE)==ADC_TSC_MODE)
adc_disableInt(eADC_WT_INT);
if(g_psADCCallBack[eADC_WT_INT]!=0)
g_psADCCallBack[eADC_WT_INT]();
g_bIsWTInt = TRUE;
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & /* Clean the touch panel interrupt */
~(LVD_INT | ADC_INT)) |
(WT_INT |ADC_INT));
return;
}
u32Reg = inp32(REG_AUDIO_CON);
if( (u32Reg & (AUDIO_INT_EN | AUDIO_INT)) == (AUDIO_INT_EN | AUDIO_INT))
{//Audio record interrupt
if(g_psADCCallBack[eADC_AUD_INT]!=0)
g_psADCCallBack[eADC_AUD_INT]();
g_bIsAudioInt = TRUE;
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) | AUDIO_INT); /* Clean the record interrupt */
}
}
UINT32
adc_installCallback(
E_ADC_INT eIntType,
PFN_ADC_CALLBACK pfnCallback,
PFN_ADC_CALLBACK* pfnOldCallback
)
{
switch(eIntType)
{
case eADC_ADC_INT:
*pfnOldCallback = g_psADCCallBack[eADC_ADC_INT];
g_psADCCallBack[eADC_ADC_INT] = pfnCallback;
break;
case eADC_AUD_INT:
*pfnOldCallback = g_psADCCallBack[eADC_AUD_INT];
g_psADCCallBack[eADC_AUD_INT] = pfnCallback;
break;
case eADC_LVD_INT:
*pfnOldCallback = g_psADCCallBack[eADC_LVD_INT];
g_psADCCallBack[eADC_LVD_INT] = pfnCallback;
break;
case eADC_WT_INT:
*pfnOldCallback = g_psADCCallBack[eADC_WT_INT];
g_psADCCallBack[eADC_WT_INT] = pfnCallback;
break;
default:
return E_ADC_INVALID_INT;
}
return Successful;
}
void adc_setWorkingFreq(UINT32 u32WorkingFreq)
{
UINT32 u32WorkingKHz, u32UpllKHz, u32ApllKHz;
UINT32 u32Div, u32Div0, u32Div1;
UINT32 u32ADCSrc;
u32WorkingKHz = sysGetExternalClock();
u32UpllKHz = sysGetPLLOutputKhz(eSYS_UPLL, u32WorkingKHz);
DBG_PRINTF("UPLL output clock = %dMHz\n", u32UpllKHz/1000);
u32ApllKHz = sysGetPLLOutputKhz(eSYS_APLL, u32WorkingKHz);
DBG_PRINTF("APLL output clock = %dMHz\n", u32ApllKHz/1000);
if( (u32UpllKHz > 25000) )
{//>25MHz.
u32ADCSrc = 0x18<<16;
u32Div = u32UpllKHz/u32WorkingFreq;
if( (u32UpllKHz%u32WorkingFreq) != 0)
u32Div = u32Div +1;
u32WorkingKHz = u32UpllKHz/u32Div;
}
else if (u32ApllKHz> 25000)
{//>25MHz
u32ADCSrc = 0x10<<16;
u32Div = u32ApllKHz/u32WorkingFreq;
if( (u32ApllKHz%u32WorkingFreq) !=0)
u32Div = u32Div +1;
u32WorkingKHz = u32ApllKHz/u32Div;
}
/* Search for fit divider */
for(u32Div1=1; u32Div1<256; u32Div1=u32Div1+1)
{
for(u32Div0=1; u32Div0<8; u32Div0=u32Div0+1)
{//u32Div0!=0
if((u32Div0*u32Div1)==u32Div)
break;
}
if((u32Div0*u32Div1)==u32Div)
break;
}
if(u32Div0>=1)
u32Div0 = u32Div0 -1;
if( u32Div1>=1)
u32Div1 = u32Div1 -1;
DBG_PRINTF("Total divider = %d\n", u32Div);
DBG_PRINTF("Div0 = %d, Div1 = %d \n", u32Div0, u32Div1);
DBG_PRINTF("ADC working frequency = %d\n", u32WorkingKHz);
outp32(REG_CLKDIV3, (inp32(REG_CLKDIV3) & ~(ADC_N1 | ADC_S | ADC_N0)) |
((u32ADCSrc) | ((u32Div0<<16) | (u32Div1<<24))) );
}
/*-----------------------------------------------------------------------------------------------------------
Function: adc_init
The function initialize the ADC IP.
1. Get the PLL as system clock source.
2. Set the working frequency. Max frequency = 25MHz
-----------------------------------------------------------------------------------------------------------*/
void adc_init(void)
{
//WB_CLKFREQ_T clk;
//sysGetClockFreq(&clk);
outp32(REG_APBCLK, inp32(REG_APBCLK) | ADC_CKE);
adc_setWorkingFreq(100*50);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
outp32(REG_ADC_CON, inp32(REG_ADC_CON) | ADC_CON_ADC_EN);
_opened = E_ADC_INIT;
}
/*-----------------------------------------------------------------------------------------------------------
Function: adc_normalRead
The function is use to converse the voltage(analog) to 10 bits gigital data
u32Channel = 2, 3, 4.
-----------------------------------------------------------------------------------------------------------*/
UINT32 adc_normalread(UINT32 u32Channel, PUINT16 pu16Data)
{
if( (u32Channel>4)&&(u32Channel<2) )
return E_DRVADC_INVALID_CHANNEL;
if(_state != ADC_STATE_WT)
return E_DRVADC_INVALID_TIMING;
adc_disableInt(eADC_WT_INT);
adc_setTouchScreen(eADC_TSCREEN_AUTO, //E_DRVADC_TSC_MODE eTscMode,
0x150,
TRUE, //BOOL bIsPullup,
TRUE);
adc_enableInt(eADC_ADC_INT);
outp32( REG_ADC_CON,( ADC_CON_ADC_EN | ADC_CONV | ADC_INT
| (u32Channel<<9)) );
DrvADC_Conversion();
//while( (inp32(REG_ADC_CON) & ADC_INT) != ADC_INT); /* Wait until ADC INT */
DrvADC_PollingADC();
DrvADC_GetNormalData(pu16Data);
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & ~(ADC_TSC_MODE|ADC_MUX))|(ADC_INT | WT_INT));
/* set to WT mode */
adc_setTouchScreen(eADC_TSCREEN_TRIG, //E_DRVADC_TSC_MODE eTscMode,
0x150,
TRUE, //BOOL bIsPullup,
TRUE); //BOOL bMAVFilter
adc_enableInt(eADC_ADC_INT);
adc_enableInt(eADC_WT_INT);
return Successful;
}
/*-----------------------------------------------------------------------------------------------------------
Function: adc_open
The function open ADC driver
1. Set the working frequency. Max frequency = 25MHz
-----------------------------------------------------------------------------------------------------------*/
int adc_open(unsigned char type, unsigned short hr, unsigned short vr)
{
if(_opened == 0)
adc_init();
if(_opened != 1)
return(-1);
_opened = 2;
switch (type)
{
case ADC_TS_4WIRE:
outp32(REG_APBCLK, inp32(REG_APBCLK) | ADC_CKE);
#if 0
adc_setTouchScreen(eADC_TSCREEN_TRIG, //E_DRVADC_TSC_MODE eTscMode,
150,
TRUE, //BOOL bIsPullup,
FALSE); //MAV enable
adc_setWorkingFreq(100*50); //100 KHz
#else
adc_setTouchScreen(eADC_TSCREEN_TRIG, //E_DRVADC_TSC_MODE eTscMode,
0x180,
TRUE, //BOOL bIsPullup,
FALSE); //MAV enable
#endif
break;
return(-1);
}
_hr = hr;
outp32(REG_CLKDIV3, (inp32(REG_CLKDIV3) & ~(ADC_N1 | ADC_S | ADC_N0) ) | (1<<24)); //Come from XTAL directly
_vr = vr;
sysInstallISR(IRQ_LEVEL_7, IRQ_ADC, (PVOID)adc_isr);
sysEnableInterrupt(IRQ_ADC);
_opened = E_ADC_OPEN;
return(0);
}
void adc_close(void)
{
if(_opened != 2)
return;
sysDisableInterrupt(IRQ_ADC);
outp32(REG_ADC_CON, inp32(REG_ADC_CON) & ~ADC_CON_ADC_EN);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
outp32(REG_APBCLK, inp32(REG_APBCLK) & ~ADC_CKE);
_opened = E_ADC_UNINIT;
return;
}
void printlist(UINT16 list[],int n)
{
int i;
for(i=0;i<n;i++)
sysprintf("%d\t",list[i]);
sysprintf("\n");
}
/*-----------------------------------------------------------------------------------------------------------
Function adc_read.
Get touch panel position.
mode: ADC_NONBLOCK or ADC_BLOCK.
x: X position
y: Y position
return 0: No any position. The (x, y) is unavilable.
1: Panel was touched. The (x, y) is avilable.
-----------------------------------------------------------------------------------------------------------*/
int adc_read(unsigned char mode, unsigned short *x, unsigned short *y)
{
volatile UINT32 u32Idx=0;
UINT16 au16XPos[SORT_FIFO];
UINT16 au16YPos[SORT_FIFO];
BOOL bIsXnear, bIsYnear;
//_state = ADC_STATE_WT;
if(_opened != 2)
return(-1);
if(mode != ADC_NONBLOCK && mode != ADC_BLOCK) {
sysDisableInterrupt(IRQ_ADC);
return(-1);
}
/*0211 */
outp32(REG_ADC_CON, (inp32(REG_ADC_CON) & ~ADC_TSC_MODE) | (2 << 14) );
adc_disableInt(eADC_ADC_INT);
/* set to WT mode */
adc_setTouchScreen(eADC_TSCREEN_TRIG, //E_DRVADC_TSC_MODE eTscMode,
0x180,
FALSE, //BOOL bIsPullup,
FALSE); //BOOL bMAVFilter
g_bIsWTInt = 0;
adc_enableInt(eADC_WT_INT);
u32Idx=0x10;
while(u32Idx--);
if(mode == ADC_BLOCK)
{
#ifdef USING_INT
while(g_bIsWTInt==0);
#else
DrvADC_PollingWT();
#endif
}
/*0211 */
else
{
#ifdef USING_INT
if(g_bIsWTInt==0)
#else
if(DrvADC_IsPenDown()==FALSE)
#endif
return 0; //Means pen up.
}
/*0211 */
/* set to Auto mode */
/*0211 */
adc_disableInt(eADC_WT_INT);
/*0211 */
g_bIsADCInt = 0;
adc_setTouchScreen(eADC_TSCREEN_AUTO, //E_DRVADC_TSC_MODE eTscMode,
0x180,
FALSE, //BOOL bIsPullup,
FALSE);
/*0211 */
adc_enableInt(eADC_ADC_INT);
/*0211 */
g_bIsADCInt = 0;
DrvADC_Conversion();
#ifdef USING_INT
while(g_bIsADCInt==0);
#else
DrvADC_PollingADC( );
#endif
u32Idx = 0x2000;
while(u32Idx--);
for(u32Idx = 0; u32Idx<SORT_FIFO; u32Idx=u32Idx+1)
{
g_bIsADCInt = 0;
DrvADC_Conversion();
#ifdef USING_INT
while(g_bIsADCInt==0);
#else
DrvADC_PollingADC( );
#endif
DrvADC_GetTscData(&au16XPos[u32Idx],&au16YPos[u32Idx]);
}
quicksort(au16XPos, 0, SORT_FIFO-1);
quicksort(au16YPos, 0, SORT_FIFO-1);
*x = (au16XPos[SORT_FIFO-4]+au16XPos[SORT_FIFO-3]+au16XPos[SORT_FIFO-2])/3;
*y = (au16YPos[SORT_FIFO-4]+au16YPos[SORT_FIFO-3]+au16YPos[SORT_FIFO-2])/3;
bIsXnear = ((i32_x-16) <*x ) && (*x <(i32_x+16));
bIsYnear = ((i32_y-16) <*y ) && (*y <(i32_y+16));
adc_setTouchScreen(eADC_TSCREEN_TRIG, //E_DRVADC_TSC_MODE eTscMode,
0x20,
FALSE, //BOOL bIsPullup,
FALSE); //BOOL bMAVFilter
i32_x = *x;
i32_y = *y;
u32Idx=0x40000;
while(u32Idx--);
if(mode == ADC_NONBLOCK)
{
//if(bIsXnear && bIsYnear)
{
#ifdef USING_INT
if(g_bIsWTInt == 0)
#else
if(DrvADC_IsPenDown()==FALSE)
#endif
{
sysprintf("Library Pen up\n");
return 0; //Means pen up.
}
else
return 1; //Means pen down.
}
return 0;
}
else
{
if(bIsXnear && bIsYnear)
{
return 1;
}
else
return 0;
}
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
DrvADC_SetOffsetCancellation()
DESCRIPTION
The function is only for OP offset callcellation
INPUTS
None
OUTPUTS
none
RETURN
Recording gain in dB.
---------------------------------------------------------------------------------------------------------*/
void DrvADC_SetOffsetCancellation(
BOOL bIsMuteEnable,
BOOL bIsOffsetCalibration,
BOOL bIsHardwareMode,
UINT32 u32Offset
)
{
outp32(REG_OPOC, (inp32(REG_OPOC) & ~(MUTE_SW | OOC | OPOCM |OPOC_SW)) |
((((bIsMuteEnable ? MUTE_SW:0) |
(bIsOffsetCalibration ? OOC:0)) |
(bIsHardwareMode ? OPOCM:0)) |
((u32Offset<<24)&OPOC_SW)) );
}
void DrvADC_GetOffsetCancellation(
PBOOL pbIsMuteEnable,
PBOOL pbIsOffsetCalibration,
PBOOL pbIsHardwareMode,
PUINT32 pu32Offset
)
{
UINT32 u32RegData = inp32(REG_OPOC);
*pbIsMuteEnable = (u32RegData & MUTE_SW)>>31;
*pbIsOffsetCalibration = (u32RegData & OOC)>>30;
*pbIsHardwareMode = (u32RegData & OPOCM)>>29;
*pu32Offset = (u32RegData & OPOC_SW)>>24;
}
void DrvADC_SetOffsetCancellationEx(
UINT32 u32SampleNumber,
UINT32 u32DelaySampleCount
)
{
outp32(REG_OPOC, (inp32(REG_OPOC) & ~(OPOC_TCSN | OPOC_DSC)) |
(((u32SampleNumber<<16) & OPOC_TCSN) |
(u32DelaySampleCount & OPOC_DSC)) );
}
void DrvADC_GetOffsetCancellationEx(
PUINT32 pu32SampleNumber,
PUINT32 pu32DelaySampleCount
)
{
UINT32 u32RegData = inp32(REG_OPOC);
*pu32SampleNumber = u32RegData & OPOC_TCSN;
*pu32DelaySampleCount = u32RegData & OPOC_DSC;
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
ADC_SetNoiseGate()
DESCRIPTION
Set Pre-Amplifer, Post-Amplifer and offset(Offset Cancellation
INPUTS
None
OUTPUTS
none
RETURN
Noise gate Level gain in -24, -30, -36, -42dB.
---------------------------------------------------------------------------------------------------------*/
void ADC_SetNoiseGate(
BOOL bIsEnable,
E_ADC_NOISEGATE eNoiseGateLevel
)
{
outp32(REG_AGC_CON, (inp32(REG_AGC_CON) & ~(NG_EN |NG_LEVEL)) |
(((bIsEnable <<31)& NG_EN) |
((eNoiseGateLevel <<12)& NG_LEVEL)) );
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
ADC_GetNoiseGate()
DESCRIPTION
Set Pre-Amplifer, Post-Amplifer and offset(Offset Cancellation
INPUTS
None
OUTPUTS
none
RETURN
Noise gate Level gain in -24, -30, -36, -42dB.
---------------------------------------------------------------------------------------------------------*/
void ADC_GetNoiseGate(
PBOOL pbIsEnable,
E_ADC_NOISEGATE* peNoiseGateLevel
)
{
UINT32 u32RegData = inp32(REG_AGC_CON);
*pbIsEnable = (u32RegData & NG_EN)>>31;
*peNoiseGateLevel = (u32RegData & NG_LEVEL)>>12;
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
DrvADC_SetAutoGainTiming()
DESCRIPTION
Set the parameter for AGC
INPUTS
u32Period Detect max peak in the how many samples
u32Attack
u32Recovery A band in the uper side from u32OutputLevel+-eUpBand
u32Hold A band in the buttom side from u32OutputLevel+-eUpBand
OUTPUTS
none
RETURN
none
---------------------------------------------------------------------------------------------------------*/
void ADC_SetAutoGainTiming(
UINT32 u32Period,
UINT32 u32Attack,
UINT32 u32Recovery,
UINT32 u32Hold
)
{
outp32(REG_AGC_CON, ( (inp32(REG_AGC_CON) & ~(PERIOD | ATTACK | RECOVERY| HOLD)) |
( ((u32Period<<16) & PERIOD) |
((u32Attack<<8) & ATTACK)) ) |
( ((u32Recovery <<4)& RECOVERY) |
(u32Hold & HOLD) ) );
}
void ADC_GetAutoGainTiming(
PUINT32 pu32Period,
PUINT32 pu32Attack,
PUINT32 pu32Recovery,
PUINT32 pu32Hold
)
{
UINT32 u32RegData = inp32(REG_AGC_CON);
*pu32Period = (u32RegData & PERIOD) >> 16;
*pu32Attack = (u32RegData & ATTACK) >> 8;
*pu32Recovery = (u32RegData & RECOVERY) >> 4;
*pu32Hold = u32RegData & HOLD;
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
ADC_SetGainControl()
DESCRIPTION
Set Pre-Amplifer and Post-Amplifer
INPUTS
None
OUTPUTS
none
RETURN
Recording gain in dB.
---------------------------------------------------------------------------------------------------------*/
void ADC_SetGainControl(
E_ADC_PREGAIN ePreGain,
E_ADC_POSTGAIN ePostGain
)
{
outp32(REG_AGCP1, (inp32(REG_AGCP1) & ~(AUDIO_VOL|PRAGA)) |
((ePreGain<<8)|ePostGain));
}
void ADC_GetGainControl(
E_ADC_PREGAIN* pePreGain,
E_ADC_POSTGAIN* pePostGain
)
{
UINT32 u32RegData = inp32(REG_AGCP1);
*pePreGain = (u32RegData & PRAGA)>>8;
*pePostGain = u32RegData & AUDIO_VOL;
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
ADC_SetAutoGainControl()
DESCRIPTION
Set the parameter for AGC
INPUTS
bIsEnable Enable AGC
u32OutputLevel Output target level
eUpBand A band in the uper side from u32OutputLevel+-eUpBand
eDownBand A band in the buttom side from u32OutputLevel+-eUpBand
OUTPUTS
none
RETURN
none
---------------------------------------------------------------------------------------------------------*/
void ADC_SetAutoGainControl(
BOOL bIsEnable,
UINT32 u32OutputLevel,
E_ADC_UPBAND eAdcUpBand,
E_ADC_DOWNBAND eAdcDownBand
)
{
outp32(REG_AGC_CON, (inp32(REG_AGC_CON) & ~AGC_EN) |
((bIsEnable <<30)& AGC_EN) );
outp32(REG_AGCP1, ( (inp32(REG_AGCP1) & ~(OTL | UPBAND | DOWNBAND)) |
((u32OutputLevel<<12) & OTL) ) |
(((eAdcUpBand <<11)& UPBAND) |
((eAdcDownBand <<10)& DOWNBAND)) );
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
ADC_GetAutoGainControl()
DESCRIPTION
Set Pre-Amplifer, Post-Amplifer and offset(Offset Cancellation
INPUTS
None
OUTPUTS
bIsEnable Enable AGC
u32OutputLevel Output target level
eUpBand A band in the uper side from u32OutputLevel+-eUpBand
eDownBand A band in the buttom side from u32OutputLevel+-eUpBand
RETURN
None.
---------------------------------------------------------------------------------------------------------*/
void ADC_GetAutoGainControl(
PBOOL pbIsEnable,
PUINT32 pu32OutputLevel,
E_ADC_UPBAND* peAdcUpBand,
E_ADC_DOWNBAND* peAdcDownBand
)
{
UINT32 u32RegData = inp32(REG_AGC_CON);
*pbIsEnable = (u32RegData & AGC_EN)>>30;
u32RegData = inp32(REG_AGCP1);
*pu32OutputLevel = (u32RegData & OTL)>>12;
*peAdcUpBand = (u32RegData & UPBAND)>>11;
*peAdcDownBand = (u32RegData & DOWNBAND)>>10;
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
Audio_Open()
DESCRIPTION
Open the ADC conversion or Audio record function
INPUTS
mode: The work mode of ADC. It could be in normal
ADC conversion mode or audio recording mode
u32ConvClock:
If working in ADC_NORMAL mode, u32ConvClock is the
conversion rate.
If working in ADC_RECORD mode, u32ConvClock is the
sampling rate.
OUTPUTS
none
RETURN
E_SUCCESS Success
E_DRVADC_ARGUMENT Wrong argument
E_DRVADC_CLOCK Unable to output a suitable clock
---------------------------------------------------------------------------------------------------------*/
BOOL bIsAudioInitialize = FALSE;
INT32 audio_Open(E_SYS_SRC_CLK eSrcClock, UINT32 u32ConvClock)
{
UINT32 u32PllOutKHz, u32ExtFreq;
UINT32 u32Tmp;
UINT32 u32Reg;
volatile UINT32 u32Dly=0x100;
/* Enable clock and IP reset */
outp32(REG_APBCLK, inp32(REG_APBCLK) | ADC_CKE);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) | ADCRST);
outp32(REG_APBIPRST, inp32(REG_APBIPRST) & ~ADCRST);
/* Default to use conv bit to control conversion */
u32Reg = 0;
u32Reg = u32Reg | (ADC_CON_ADC_EN); /* Enable ADC */
/* Use the same clock source as system */
outp32(REG_CLKDIV3, (inp32(REG_CLKDIV3) & ~ADC_S) |
(eSrcClock << 19));
switch(eSrcClock)
{
case eSYS_X32K:
return -1; /* Wrong clock source */
break;
case eSYS_APLL:
case eSYS_UPLL:
{
UINT32 u32TotalDiv;
UINT32 u32IdxN0, u32IdxN1;
UINT32 u32IdxN00, u32IdxN11;
u32ExtFreq = sysGetExternalClock();
u32PllOutKHz = sysGetPLLOutputKhz(eSrcClock, u32ExtFreq);
if(u32PllOutKHz==169333)
u32PllOutKHz = 169344;
sysprintf("PLL clock = %d KHz\n", u32PllOutKHz);
//if(eDRVADC_Mode == eDRVADC_RECORD)
u32TotalDiv = (u32PllOutKHz*1000)/(1280*u32ConvClock);
//else
// u32TotalDiv = (u32PllOutKHz/50)/u32ConvClock;
if(u32TotalDiv>(8*256))
return -1;
sysprintf("Total divider = %d\n", u32TotalDiv);
for(u32IdxN1=1;u32IdxN1<=256;u32IdxN1=u32IdxN1+1)
{
for(u32IdxN0=2;u32IdxN0 <= 8;u32IdxN0=u32IdxN0+1)
{//u32IdxN0 != 1
if(u32TotalDiv==(u32IdxN0*u32IdxN1))
{
u32IdxN00 = u32IdxN0;
u32IdxN11 = u32IdxN1;
sysprintf("DIV_N1, DIV_N0 = %d, %d\n", u32IdxN11, u32IdxN00);
break;
}
}
if(u32TotalDiv==((u32IdxN00)*u32IdxN11))
break;
}
u32Tmp = (inp32(REG_CLKDIV3) & ~(ADC_N1 | ADC_S | ADC_N0)) |
( (((u32IdxN11-1) <<24) | ((u32IdxN00-1) << 16) | (eSrcClock<<19) ));
outp32(REG_CLKDIV3, u32Tmp);
}
break;
case eSYS_EXT:
{
UINT32 u32ExtClk, u32AdcDivN1;
u32ExtClk = sysGetExternalClock();
u32AdcDivN1 = (u32ExtClk)/u32ConvClock;
if(u32AdcDivN1>256)
return -1;
outp32(REG_CLKDIV3, (inp32(REG_CLKDIV3) & ~(ADC_N1 | ADC_N0)) |
((u32AdcDivN1-1) <<24) );
}
break;
}
outp32(REG_ADC_CON, u32Reg);
/* Reset Record Function */
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) | AUDIO_RESET);
while(u32Dly--);
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) & ~(AUDIO_RESET));
/* Default to Audio Interrupt Mode 3, op offset:b'1000, interrupt enabled */
outp32(REG_AUDIO_CON, (AUDIO_HPEN | AUDIO_INT | AUDIO_INT_EN |AUDIO_VOL_EN | AUDIO_RESET));
outp32(REG_AUDIO_CON, (inp32(REG_AUDIO_CON) & ~(AUDIO_CCYCLE | AUDIO_RESET)) | (0x50<<16));//ADC cycle = 50
/* Hardware offset calibration */
if(bIsAudioInitialize==FALSE)
{
bIsAudioInitialize = TRUE;
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) |
( AUDIO_INT | AUDIO_EN ) );
DrvADC_SetOffsetCancellation(FALSE, //BOOL bIsMuteEnable,
FALSE, //BOOL bIsOffsetCalibration,
TRUE, //BOOL bIsHardwareMode,
0x10); //UINT32 u32Offset
DrvADC_SetOffsetCancellationEx(1, //255 sample
256);//Delay sample count
{
volatile unsigned int btime, etime;
btime = etime = sysGetTicks(TIMER0);
while( (etime - btime) <= 10 )
{
etime = sysGetTicks(TIMER0);
}
}
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) & ~AUDIO_EN);
DrvADC_SetOffsetCancellation(FALSE, //BOOL bIsMuteEnable,
FALSE, //BOOL bIsOffsetCalibration,
FALSE, //BOOL bIsHardwareMode,
0x10); //UINT32 u32Offset
}
/* Set ADC Parameter for audio recording*/
//outp32(REG_AUDIO_CON, (inp32(REG_AUDIO_CON) & ~(AUDIO_INT_MODE)) | (1<<30));
outp32(REG_AUDIO_CON, (inp32(REG_AUDIO_CON) & ~(AUDIO_INT_MODE)) );
ADC_SetNoiseGate(FALSE, eADC_NG_N36);
ADC_SetAutoGainTiming(4, //Period
4, //Attack
4,
4);
ADC_SetGainControl(eADC_PRE_P14, //Pre-gain 14db
eADC_POST_P0); //Post-gain is invalid if enable AGC
ADC_SetAutoGainControl(TRUE, //AGC enable
13, //Output target aszOTLArray[13] = -9db
eADC_BAND_P0P5,
eADC_BAND_N0P5);
outp32(0xb800E000, inp32(0xb800E000) & ~BIT8); //Audio data src from Audio buffer
sysInstallISR(IRQ_LEVEL_7, IRQ_ADC, (PVOID)adc_isr);
sysEnableInterrupt(IRQ_ADC);
return 0;
}
/*----------------------------------------------------------------------------------------------------------
FUNCTION
adc_StartRecord()
DESCRIPTION
Start to record Audio data. This function only can be used in
ADC_RECORD mode.
INPUTS
none
OUTPUTS
none
RETURN
none
----------------------------------------------------------------------------------------------------------*/
void adc_StartRecord(void)
{
//Enable Co-work with EDMA
outp32(REG_AGCP1, inp32(REG_AGCP1) | EDMA_MODE);
// Clean INT status for safe
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) |
(AUDIO_RESET | AUDIO_INT) );
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) &
~(AUDIO_RESET | AUDIO_INT) );
//Enable record function
#if 0
outp32(REG_AUDIO_CON, (inp32(REG_AUDIO_CON) & ~AUDIO_INT_MODE) |
(((1 << 30) & AUDIO_INT_MODE) |
AUDIO_EN) );
#else
outp32(REG_AUDIO_CON, (inp32(REG_AUDIO_CON) & ~AUDIO_INT_MODE) |
(((0 << 30) & AUDIO_INT_MODE) |
AUDIO_EN) );
#endif
}
/*----------------------------------------------------------------------------------------------------------
FUNCTION
adc_StopRecord()
DESCRIPTION
Stop recording Audio data. This function only can be used in
ADC_RECORD mode.
INPUTS
none
OUTPUTS
none
RETURN
none
----------------------------------------------------------------------------------------------------------*/
void adc_StopRecord(void)
{
//Disable record function
outp32(REG_AGCP1, inp32(REG_AGCP1) & ~EDMA_MODE);
outp32(REG_AUDIO_CON, inp32(REG_AUDIO_CON) & (~AUDIO_EN));
}
/*---------------------------------------------------------------------------------------------------------
FUNCTION
adc_GetRecordData()
DESCRIPTION
Get the converted ADC value in ADC_RECORD mode
INPUTS
none
OUTPUTS
none
RETURN
The pointer to the record data. The data length is 8 samples
---------------------------------------------------------------------------------------------------------*/
PINT16
adc_GetRecordData(
void
)
{
//Return the base address of converted data. There are 8 samples
return (PINT16)REG_AUDIO_BUF0;
}
void ADC_Test2(void) {
UINT16 val;
UINT32 index;
adc_init();
adc_open(ADC_TS_4WIRE, 320, 240);
while (1) {
if (adc_normalread(2, &val)==Successful) {
sysprintf("2:ADC Value = %d\n", val);
}
if (adc_normalread(3, &val)==Successful) {
sysprintf("3:ADC Value = %d\n", val);
}
for (index = 0; index < 40000 * 100; index ++);
}
}
libgpio.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/****************************************************************************
* *
* Copyright (c) 2009 Nuvoton Tech. Corp. All rights reserved. *
* *
*****************************************************************************/
/****************************************************************************
* FILENAME
* libgpio.c
*
* VERSION
* 1.0
*
* DESCRIPTION
* GPIO library source code
*
* DATA STRUCTURES
* None
*
* FUNCTIONS
*
* HISTORY
*
* REMARK
* None
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wblib.h"
#include "w55fa93_gpio.h"
// accetiable debounce clock
static const unsigned int _clk[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 2*256, 4*256, 8*256, 16*256, 32*256, 64*256, 128*256};
int gpio_open(unsigned char port)
{
switch (port) {
case GPIO_PORTA:
outpw(REG_GPAFUN , inpw(REG_GPAFUN) &~ (0xF00000));
break;
case GPIO_PORTD:
outpw(REG_GPDFUN , inpw(REG_GPDFUN) &~ (0xFF0003FF));
break;
case GPIO_PORTE:
outpw(REG_GPEFUN , inpw(REG_GPEFUN) &~ (0xFF0));
break;
case GPIO_PORTB:
case GPIO_PORTC:
break;
default:
return(-1);
}
return(0);
}
int gpio_configure(unsigned char port, unsigned short num)
{
switch (port) {
case GPIO_PORTA:
if(num<=11)
outpw(REG_GPAFUN , inpw(REG_GPAFUN) &~ (0x3 << (num<<1)));
else
return(-1);
break;
case GPIO_PORTB:
outpw(REG_GPBFUN , inpw(REG_GPBFUN) &~ (0x3 << (num<<1)));
break;
case GPIO_PORTC:
outpw(REG_GPCFUN , inpw(REG_GPCFUN) &~ (0x3 << (num<<1)));
break;
case GPIO_PORTD:
outpw(REG_GPDFUN , inpw(REG_GPDFUN) &~ (0x3 << (num<<1)));
break;
case GPIO_PORTE:
if(num<=11)
outpw(REG_GPEFUN , inpw(REG_GPEFUN) &~ (0x3 << (num<<1)));
else
return(-1);
break;
default:
return(-1);
}
return(0);
}
int gpio_readport(unsigned char port, unsigned short *val)
{
switch (port) {
case GPIO_PORTA:
*val = (inpw(REG_GPIOA_PIN) & 0x0fff);
break;
case GPIO_PORTB:
*val = (inpw(REG_GPIOB_PIN) & 0xffff);
break;
case GPIO_PORTC:
*val = (inpw(REG_GPIOC_PIN) & 0xffff);
break;
case GPIO_PORTD:
*val = (inpw(REG_GPIOD_PIN) & 0xffff);
break;
case GPIO_PORTE:
*val = (inpw(REG_GPIOE_PIN) & 0x0fff);
break;
default:
return(-1);
}
return(0);
}
int gpio_setportdir(unsigned char port, unsigned short mask, unsigned short dir)
{
switch (port) {
case GPIO_PORTA:
outpw(REG_GPIOA_OMD , inpw(REG_GPIOA_OMD) & ~(mask & (mask ^ dir)));
outpw(REG_GPIOA_OMD , inpw(REG_GPIOA_OMD) | (mask & dir));
break;
case GPIO_PORTB:
outpw(REG_GPIOB_OMD , inpw(REG_GPIOB_OMD) & ~(mask & (mask ^ dir)));
outpw(REG_GPIOB_OMD , inpw(REG_GPIOB_OMD) | (mask & dir));
break;
case GPIO_PORTC:
outpw(REG_GPIOC_OMD , inpw(REG_GPIOC_OMD) & ~(mask & (mask ^ dir)));
outpw(REG_GPIOC_OMD , inpw(REG_GPIOC_OMD) | (mask & dir));
break;
case GPIO_PORTD:
outpw(REG_GPIOD_OMD , inpw(REG_GPIOD_OMD) & ~(mask & (mask ^ dir)));
outpw(REG_GPIOD_OMD , inpw(REG_GPIOD_OMD) | (mask & dir));
break;
case GPIO_PORTE:
outpw(REG_GPIOE_OMD , inpw(REG_GPIOE_OMD) & ~(mask & (mask ^ dir)));
outpw(REG_GPIOE_OMD , inpw(REG_GPIOE_OMD) | (mask & dir));
break;
default:
return(-1);
}
return(0);
}
int gpio_setportval(unsigned char port, unsigned short mask, unsigned short val)
{
switch (port) {
case GPIO_PORTA:
outpw(REG_GPIOA_DOUT , inpw(REG_GPIOA_DOUT) & ~(mask & (mask ^ val)));
outpw(REG_GPIOA_DOUT , inpw(REG_GPIOA_DOUT) | (mask & val));
break;
case GPIO_PORTB:
outpw(REG_GPIOB_DOUT , inpw(REG_GPIOB_DOUT) & ~(mask & (mask ^ val)));
outpw(REG_GPIOB_DOUT , inpw(REG_GPIOB_DOUT) | (mask & val));
break;
case GPIO_PORTC:
outpw(REG_GPIOC_DOUT , inpw(REG_GPIOC_DOUT) & ~(mask & (mask ^ val)));
outpw(REG_GPIOC_DOUT , inpw(REG_GPIOC_DOUT) | (mask & val));
break;
case GPIO_PORTD:
outpw(REG_GPIOD_DOUT , inpw(REG_GPIOD_DOUT) & ~(mask & (mask ^ val)));
outpw(REG_GPIOD_DOUT , inpw(REG_GPIOD_DOUT) | (mask & val));
break;
case GPIO_PORTE:
outpw(REG_GPIOE_DOUT , inpw(REG_GPIOE_DOUT) & ~(mask & (mask ^ val)));
outpw(REG_GPIOE_DOUT , inpw(REG_GPIOE_DOUT) | (mask & val));
break;
default:
return(-1);
}
return(0);
}
int gpio_setportpull(unsigned char port, unsigned short mask, unsigned short pull)
{
switch (port) {
case GPIO_PORTA:
outpw(REG_GPIOA_PUEN , inpw(REG_GPIOA_PUEN) & ~(mask & (mask ^ pull)));
outpw(REG_GPIOA_PUEN , inpw(REG_GPIOA_PUEN) | (mask & pull));
break;
case GPIO_PORTB:
outpw(REG_GPIOB_PUEN , inpw(REG_GPIOB_PUEN) & ~(mask & (mask ^ pull)));
outpw(REG_GPIOB_PUEN , inpw(REG_GPIOB_PUEN) | (mask & pull));
break;
case GPIO_PORTC:
outpw(REG_GPIOC_PUEN , inpw(REG_GPIOC_PUEN) & ~(mask & (mask ^ pull)));
outpw(REG_GPIOC_PUEN , inpw(REG_GPIOC_PUEN) | (mask & pull));
break;
case GPIO_PORTD:
outpw(REG_GPIOD_PUEN , inpw(REG_GPIOD_PUEN) & ~(mask & (mask ^ pull)));
outpw(REG_GPIOD_PUEN , inpw(REG_GPIOD_PUEN) | (mask & pull));
break;
case GPIO_PORTE:
outpw(REG_GPIOE_PUEN , inpw(REG_GPIOE_PUEN) & ~(mask & (mask ^ pull)));
outpw(REG_GPIOE_PUEN , inpw(REG_GPIOE_PUEN) | (mask & pull));
break;
default:
return(-1);
}
return(0);
}
int gpio_setdebounce(unsigned int clk, unsigned char src)
{
int i;
if(clk > 128*256 || src > 0xf)
return(-1);
// clk could only be 1, 2, 4, 8, ... 128*256
for(i = 0 ; i < 16; i++) {
if(_clk[i] == clk)
break;
}
if(i == 16)
return(-1);
outpw(REG_DBNCECON , (i << 4 | src));
return(0);
}
void gpio_getdebounce(unsigned int *clk, unsigned char *src)
{
*clk = _clk[(inpw(REG_DBNCECON) >> 4) & 0xf];
*src = inpw(REG_DBNCECON) & 0xf;
return;
}
int gpio_setsrcgrp(unsigned char port, unsigned short mask, unsigned char irq)
{
const unsigned int _irq[4] = {0, 0x55555555, 0xaaaaaaaa, 0xffffffff};
unsigned int _mask = 0;
int i;
if(irq > 3)
return(-1);
if(mask > 0xffff)
return(-1);
for(i = 0; i < 16; i++) {
if(mask & (1 << i))
_mask += (3 << (i << 1));
}
switch (port) {
case GPIO_PORTA:
outpw(REG_IRQSRCGPA , inpw(REG_IRQSRCGPA) & ~_mask);
outpw(REG_IRQSRCGPA , inpw(REG_IRQSRCGPA) | (_mask & _irq[irq]));
break;
case GPIO_PORTB:
outpw(REG_IRQSRCGPB , inpw(REG_IRQSRCGPB) & ~_mask);
outpw(REG_IRQSRCGPB , inpw(REG_IRQSRCGPB) | (_mask & _irq[irq]));
break;
case GPIO_PORTC:
outpw(REG_IRQSRCGPC , inpw(REG_IRQSRCGPC) & ~_mask);
outpw(REG_IRQSRCGPC , inpw(REG_IRQSRCGPC) | (_mask & _irq[irq]));
break;
case GPIO_PORTD:
outpw(REG_IRQSRCGPD , inpw(REG_IRQSRCGPD) & ~_mask);
outpw(REG_IRQSRCGPD , inpw(REG_IRQSRCGPD) | (_mask & _irq[irq]));
break;
case GPIO_PORTE:
outpw(REG_IRQSRCGPE , inpw(REG_IRQSRCGPE) & ~_mask);
outpw(REG_IRQSRCGPE , inpw(REG_IRQSRCGPE) | (_mask & _irq[irq]));
break;
default:
return(-1);
}
return(0);
}
int gpio_getsrcgrp(unsigned char port, unsigned int *val)
{
switch (port) {
case GPIO_PORTA:
*val = inpw(REG_IRQSRCGPA);
break;
case GPIO_PORTB:
*val = inpw(REG_IRQSRCGPB);
break;
case GPIO_PORTC:
*val = inpw(REG_IRQSRCGPC);
break;
case GPIO_PORTD:
*val = inpw(REG_IRQSRCGPD);
break;
case GPIO_PORTE:
*val = inpw(REG_IRQSRCGPE);
break;
default:
return(-1);
}
return(0);
}
int gpio_setintmode(unsigned char port, unsigned short mask, unsigned short falling, unsigned short rising)
{
if(mask > 0xffff)
return(-1);
switch (port) {
case GPIO_PORTA:
outpw(REG_IRQENGPA , inpw(REG_IRQENGPA) & ~((mask << 16) | mask));
outpw(REG_IRQENGPA , inpw(REG_IRQENGPA) | (((mask & rising) << 16) | (mask & falling)));
break;
case GPIO_PORTB:
outpw(REG_IRQENGPB , inpw(REG_IRQENGPB) & ~((mask << 16) | mask));
outpw(REG_IRQENGPB , inpw(REG_IRQENGPB) | (((mask & rising) << 16) | (mask & falling)));
break;
case GPIO_PORTC:
outpw(REG_IRQENGPC , inpw(REG_IRQENGPC) & ~((mask << 16) | mask));
outpw(REG_IRQENGPC , inpw(REG_IRQENGPC) | (((mask & rising) << 16) | (mask & falling)));
break;
case GPIO_PORTD:
outpw(REG_IRQENGPD , inpw(REG_IRQENGPD) & ~((mask << 16) | mask));
outpw(REG_IRQENGPD , inpw(REG_IRQENGPD) | (((mask & rising) << 16) | (mask & falling)));
break;
case GPIO_PORTE:
outpw(REG_IRQENGPE , inpw(REG_IRQENGPE) & ~((mask << 16) | mask));
outpw(REG_IRQENGPE , inpw(REG_IRQENGPE) | (((mask & rising) << 16) | (mask & falling)));
break;
default:
return(-1);
}
return(0);
}
int gpio_getintmode(unsigned char port, unsigned short *falling, unsigned short *rising)
{
switch (port) {
case GPIO_PORTA:
*rising = inpw(REG_IRQENGPA) >> 16;
*falling = inpw(REG_IRQENGPA) & 0xffff;
break;
case GPIO_PORTB:
*rising = inpw(REG_IRQENGPB) >> 16;
*falling = inpw(REG_IRQENGPB) & 0xffff;
break;
case GPIO_PORTC:
*rising = inpw(REG_IRQENGPC) >> 16;
*falling = inpw(REG_IRQENGPC) & 0xffff;
break;
case GPIO_PORTD:
*rising = inpw(REG_IRQENGPD) >> 16;
*falling = inpw(REG_IRQENGPD) & 0xffff;
break;
case GPIO_PORTE:
*rising = inpw(REG_IRQENGPE) >> 16;
*falling = inpw(REG_IRQENGPE) & 0xffff;
break;
default:
return(-1);
}
return(0);
}
int gpio_setlatchtrigger(unsigned char src)
{
if(src > 0xf)
return(-1);
outpw(REG_IRQLHSEL , src);
return(0);
}
void gpio_getlatchtrigger(unsigned char *src)
{
*src = inpw(REG_IRQLHSEL) & 0xf;
return;
}
int gpio_getlatchval(unsigned char port, unsigned short *val)
{
switch (port) {
case GPIO_PORTA:
*val = inpw(REG_IRQLHGPA) & 0xffff;
break;
case GPIO_PORTB:
*val = inpw(REG_IRQLHGPB) & 0xffff;
break;
case GPIO_PORTC:
*val = inpw(REG_IRQLHGPC) & 0xffff;
break;
case GPIO_PORTD:
*val = inpw(REG_IRQLHGPD) & 0xffff;
break;
case GPIO_PORTE:
*val = inpw(REG_IRQLHGPE) & 0xffff;
break;
default:
return(-1);
}
return(0);
}
int gpio_gettriggersrc(unsigned char port, unsigned short *src)
{
switch (port) {
case GPIO_PORTA:
*src = inpw(REG_IRQTGSRC0) & 0xffff;
break;
case GPIO_PORTB:
*src = (inpw(REG_IRQTGSRC0) & 0xffff0000) >> 16;
break;
case GPIO_PORTC:
*src = inpw(REG_IRQTGSRC1) & 0xffff;
break;
case GPIO_PORTD:
*src = (inpw(REG_IRQTGSRC1) & 0xffff0000) >> 16;
break;
case GPIO_PORTE:
*src = inpw(REG_IRQTGSRC2) & 0xffff;
break;
default:
return(-1);
}
return(0);
}
int gpio_cleartriggersrc(unsigned char port)
{
switch (port) {
case GPIO_PORTA:
outpw(REG_IRQTGSRC0 , inpw(REG_IRQTGSRC0) & 0xffff);
break;
case GPIO_PORTB:
outpw(REG_IRQTGSRC0 , inpw(REG_IRQTGSRC0) & 0xffff0000);
break;
case GPIO_PORTC:
outpw(REG_IRQTGSRC1 , inpw(REG_IRQTGSRC1) & 0xffff);
break;
case GPIO_PORTD:
outpw(REG_IRQTGSRC1 , inpw(REG_IRQTGSRC1) & 0xffff0000);
break;
case GPIO_PORTE:
outpw(REG_IRQTGSRC2 , inpw(REG_IRQTGSRC2) & 0xffff);
break;
default:
return(-1);
}
return(0);
}
main.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "wblib.h"
#include "w55fa93_edma.h"
#include "w55fa93_gpio.h"
#include "w55fa93_spi.h"
#include "w55fa93_adc.h"
#include "XTPH.h"
#include "XADC.h"
#define APBCLK 48000000
extern void DemoAPI_Timer0(void);
void ram_size(int Arg2, int Arg3 )
{
while (1)
{
VOID *p = malloc(Arg2 * 1024);
if (p)
{
//sysprintf("\r\n Heap space remaining %d KByte", Arg2);
free(p);
break;
}
Arg2 -= ((Arg2-Arg3) ? Arg3 : 1);
}
}
static int record = 1;
static int record_index = 1;
void step(int i)
{
if ((record + 1) != i)
{
sysprintf("r=%d\n", record_index);
sysPutChar('0' + record);
sysPutChar('0' + i);
sysPutChar('M');
}
record = i;
if (i == 7)
record = 1;
record_index ++;
}
void ii_main(void)
{
WB_UART_T uart;
UINT32 u32ExtFreq, u32Item;
UINT8 u8Item;
u32ExtFreq = sysGetExternalClock();
sysSetSystemClock(eSYS_UPLL, //E_SYS_SRC_CLK eSrcClk,
192000, //UINT32 u32PllKHz,
192000, //UINT32 u32SysKHz,
192000, //UINT32 u32CpuKHz,
96000, //UINT32 u32HclkKHz,
APBCLK/1000); //UINT32 u32ApbKHz
uart.uiFreq = u32ExtFreq*1000;
//uart.uiBaudrate = 230400; // ch_20220811
uart.uiBaudrate = 921600; // ch_20220811
uart.uiDataBits = WB_DATA_BITS_8;
uart.uiStopBits = WB_STOP_BITS_1;
uart.uiParity = WB_PARITY_NONE;
uart.uiRxTriggerLevel = LEVEL_1_BYTE;
sysInitializeUART(&uart);
ADCInit();
sysprintf("Reg_ADC_Clk = %x\n", inp32(REG_CLKDIV3)); // ch_20220305
//while(1);
//u8Item = sysGetChar();
sysEnableCache(CACHE_WRITE_BACK);
//sysEnableCache(CACHE_DISABLE);
sysSetLocalInterrupt(ENABLE_FIQ_IRQ);
ram_size(1024*8, 1);
//inputTest();
return;
}
N32903.ini 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
FUNC void DRAMInit(void)
{
_WDWORD(0xb0000204, 0xFFFFFFFF);
_WDWORD(0xb0003000, 0x0013044E);
_WDWORD(0xb0003030, 0x00001010);
_WDWORD(0xb0003010, 0x00000003);
_WDWORD(0xb0003004, 0x00000021);
_WDWORD(0xb0003004, 0x00000023);
_WDWORD(0xb0003004, 0x00000027);
_WDWORD(0xb000301C, 0x00001002);
_WDWORD(0xb0003018, 0x00000132);
_WDWORD(0xb0003004, 0x00000027);
_WDWORD(0xb0003004, 0x0000002B);
_WDWORD(0xb0003004, 0x0000002B);
_WDWORD(0xb0003018, 0x00000032);
_WDWORD(0xb0003004, 0x00000020);
_WDWORD(0xb0003034, 0x00AAAA00);
_WDWORD(0xb0003008, 0x00008035);
_WDWORD(0xb00000A0, 0x00000000);
_WDWORD(0xb0000224, 0x0000447E);
_WDWORD(0xb0000204, 0x0001011F);
_WDWORD(0xb000020C, 0x00000018);
_WDWORD(0xb000021C, 0x00000100);
_WDWORD(0xb0003028, 0x094E7425);
_WDWORD(0xb8001010, 0x00000008);
_WDWORD(0xb8001018, 0x00000008);
}
DRAMInit();
LOAD %L INCREMENTAL // Load the .axf Debug file
N32903.sct 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x00020000 0x7E0000 { ; load region size_region
ER_IROM1 0x00020000 0x7E0000 { ; load address = execution address
*.o (WB_INIT, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_RAM1 +0 { ; RW_RAM1 start address is after ER_ROM1
.ANY (+RW +ZI)
}
ZI +0 {
.ANY (.)
}
}
T168_111\core\N32903文件:第1~14个文件
最新推荐文章于 2024-10-17 11:39:06 发布