 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
strobos Član

Pridružen-a: Sre 24 Sep 2003 12:19 Prispevkov: 726 Aktiv.: 3.06 Kraj: Brežice
|
Objavljeno: Ned Jan 11, 2009 12:23 am Naslov sporočila: LPC2148 USB, IAP in RTC |
|
|
Pozdrav,
delam prenos podatkov preko USB-ja. Preko USB- ja bi rad nastavil podatke rtc-ju in dva podatka zapisal v flash z IAP, ter bral podatke rtc-ja in jih poslal PC-ju. Zdaj sem te tri stvari združil in stvar se dobro prevede brez napak. Osnova je Keilov USB HID primer. Dodal sem nastavljanje rtc-ja in pisanje na flash z iap funkcijo. Rad pa bi dodal kodo za prenos vecjega paketa podatkov (spodnja koda, ki je sposojena od teme, kjer je dal Mare69 primer), pa me zanima, kako lahko to implementiram v moj program? Prvi byte bo ukaz, nato pa s switch stavkom določim kaj se bo dogajalo naprej.
Koda: |
#include <LPC214X.H> /* LPC214x definitions */
#include "type.h"
#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "demo.h"
extern void InitRTC(void);
BYTE InReport; /* HID Input Report */
/* Bit0: Button */
/* Bit1..7: Reserved */
BYTE OutReport; /* HID Out Report */
/* Bit0..7: LEDs */
#define XTAL 12000000 // Oscillator Frequency
#ifdef BYPASS_IAP
#define CPUCLK XTAL // CPU Clock without PLL
#else
#define CPUCLK (XTAL*4) // CPU Clock with PLL
#endif
#define CCLK (XTAL / 1000) // CPU Clock without PLL in kHz
// Phase Locked Loop (PLL) definitions
#define PLL_BASE 0xE01FC080 // PLL Base Address
#define PLLCON_OFS 0x00 // PLL Control Offset
#define PLLSTAT_OFS 0x08 // PLL Status Offset
#define PLLFEED_OFS 0x0C // PLL Feed Offset
#define PLLCON_PLLE 0x01 // PLL Enable
#define PLLCON_PLLD 0x00 // PLL Disable
#define PLLCON_PLLC 0x03 // PLL Connect(0x02) | PLL Enable
#define PLLSTAT_PLOCK 0x0400 //1<<10 // PLL Lock Status
struct iap_in {
unsigned int cmd;
unsigned int par[4];
};
typedef void (*IAP)(struct iap_in *in, unsigned int *result);
#define iap_entry ((IAP) 0x7FFFFFF1) // IAP entry point
/* Default Interrupt Function: may be called when interrupts are disabled */
void def_isr (void) __irq {
;
}
#ifdef BYPASS_IAP
/*
* Switch CPU to PLL clock
*/
void start_pll (void) {
__asm {
LDR R0, =PLL_BASE
MOV R1, #0xAA
MOV R2, #0x55
// Enable PLL
MOV R3, #PLLCON_PLLE
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
// Wait until PLL Locked
LDR R2, =PLLSTAT_PLOCK
PLL_Loop:
LDR R3, [R0, #PLLSTAT_OFS]
CMP R3, R2
BEQ PLL_Loop
// Switch to PLL Clock
MOV R2, #0x55
MOV R3, #PLLCON_PLLC
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
}
}
/*
* Switch CPU to standard XTAL
*/
void stop_pll(void) __arm {
__asm {
LDR R0, =PLL_BASE
MOV R1, #0xAA
MOV R2, #0x55
// Disable PLL
MOV R3, #PLLCON_PLLD
STR R3, [R0, #PLLCON_OFS]
STR R1, [R0, #PLLFEED_OFS]
STR R2, [R0, #PLLFEED_OFS]
}
}
#endif
/*
* Convert 'addr' to sector number
*/
unsigned int get_secnum (void *addr) {
unsigned int n;
n = ((unsigned int) addr >> 13) & 0x1F; // pseudo sector number
if (n >= (0x30000 >> 13)) {
n -= 14; // high small 8kB Sectors (
}
else if (n >= (0x10000 >> 13)) {
n = 7 + (n >> 3); // large 64kB Sectors
}
return (n); // sector number
}
/*
* Erase Sector between 'start' and 'end'
* Return: IAP error code (0 when OK)
* NOTES: start needs to be a 256 byte boundary
* size should be 256, 512, 1024 or 4089
*/
unsigned int erase (void* start, void* end) {
struct iap_in iap; // IAP input parameters
unsigned int result[16]; // IAP results
unsigned int save_VicInt; // for saving of interrupt enable register
save_VicInt = VICIntEnable; // save interrupt enable status
VICIntEnClr = 0xFFFFFFFF; // disable all interrupts
#ifdef BYPASS_IAP
stop_pll(); // IAP requires to run without PLL
#endif
iap.cmd = 50; // IAP Command: Prepare Sectors for Write
iap.par[0] = get_secnum (start); // start sector
iap.par[1] = get_secnum (end); // end sector
iap_entry (&iap, result); // call IAP function
if (result[0]) goto exit; // an error occured?
iap.cmd = 52; // IAP command: Erase Flash
iap.par[0] = get_secnum (start); // start sector
iap.par[1] = get_secnum (end); // end sector
iap.par[2] = CCLK; // CPU clock
iap_entry (&iap, result); // call IAP function
exit:
#ifdef BYPASS_IAP
start_pll(); // start PLL
#endif
VICIntEnable = save_VicInt; // enable interrupts
return (result[0]);
}
/*
* Program *data to flash_addr. number of bytes specified by size
* Return: IAP error code (0 when OK)
* Note:
*/
unsigned int program (void *flash_addr, void *data, unsigned int size) {
struct iap_in iap; // IAP input parameters
unsigned int result[16]; // IAP results
unsigned int save_VicInt; // for saving of interrupt enable register
save_VicInt = VICIntEnable; // save interrupt enable status
VICIntEnClr = 0xFFFFFFFF; // disable all interrupts
#ifdef BYPASS_IAP
stop_pll(); // IAP requires to run without PLL
#endif
iap.cmd = 50; // IAP Command: Prepare Sectors for Write
iap.par[0] = get_secnum (flash_addr); // start sector
iap.par[1] = iap.par[0]; // end Sektor
iap_entry (&iap, result); // call IAP function
if (result[0]) goto exit; // an error occured?
iap.cmd = 51; // IAP Command: Copy RAM to Flash
iap.par[0] = (unsigned int) flash_addr; // destination-addr
iap.par[1] = (unsigned int) data; // source-addr
iap.par[2] = size; // number of bytes
iap.par[3] = CCLK; // CPU clock
iap_entry (&iap, result); // call IAP function
exit:
#ifdef BYPASS_IAP
start_pll(); // start PLL
#endif
VICIntEnable = save_VicInt; // enable interrupts
return (result[0]);
}
/*
* Get HID Input Report -> InReport
*/
// To, kar posljem iz kontrolerja
void GetInReport (void) {
if ((IOPIN0 & PBINT) == 0) { /* Check if PBINT is pressed */
InReport = 0x01;
} else {
InReport = 0x00;
}
}
// Konec
/*
* Set HID Output Report <- OutReport
*/
// To kar dobim v kontroler
void SetOutReport (void) {
IOPIN1 = (IOPIN1 & ~LEDMSK) | (OutReport << 16);
}
// Konec
/* Main Program */
int main (void) {
InitRTC(); //nastavitve za RTC
IODIR1 = LEDMSK; /* LED's defined as Outputs */
USB_Init(); /* USB Initialization */
USB_Connect(TRUE); /* USB Connect */
while (1); /* Loop forever */
} |
To je glavna .c datoteka, spodaj pa je koda, ki bi jo rad implementiral, da bi stvar delala tako, kot je v tej spodnji kodi.
Koda: |
void BULK_BulkOut (void) {
BYTE buf[18];
BulkLen = USB_ReadEP(BULK_EP_OUT, BulkBuf);
switch (BulkBuf[0]) {
case 1 : //set RTC
CCR = 0x10; //rtc disable
YEAR = BulkBuf[1];
MON = BulkBuf[2];
DOY = BulkBuf[3];
DOW = BulkBuf[4];
DOM = BulkBuf[5];
HOUR = BulkBuf[6];
MIN = BulkBuf[7];
SEC = BulkBuf[8];
//zapisi YEAR in DOY v Flash!
program (0x30000, YEAR, sizeof (YEAR));
program (0x31000, DOY, sizeof (DOY));
CCR = 0x11; //rtc enable
break;
case 2 : //get RTC
buf[0] = 1; //ukaz za PC
buf[1] = YEAR;
buf[2] = MON;
buf[3] = DOY;
buf[4] = DOW;
buf[5] = DOM;
buf[6] = HOUR;
buf[7] = MIN;
buf[8] = SEC;
//preberi YEAR in DOY iz flasha! Kako?
buf[9] = YEAR_flash;
buf[10] = DOY_flash;
USB_WriteEP(BULK_EP_IN, buf, 11);
break;
}
} |
In tu je še vprašanje, kako preberem podatke iz določenega naslova v flash pomnilniku?
Ima kdo program za PC, s katerim bi lahko pošiljal poljubne pakete preko usb? Sedaj imam samo en usb monitor, ki mi kaže kaj računalnik prejema od naprave, ne morem pa z njim nič poslat napravi.
Hvala in lp. |
|
Nazaj na vrh |
|
 |
alessio Član

Pridružen-a: Pon 04 Dec 2006 8:39 Prispevkov: 363 Aktiv.: 1.60 Kraj: Ljubljana
|
Objavljeno: Ned Jan 11, 2009 12:22 pm Naslov sporočila: Re: LPC2148 USB, IAP in RTC |
|
|
strobos je napisal/a: |
In tu je še vprašanje, kako preberem podatke iz določenega naslova v flash pomnilniku? |
Podatke iz določenega naslova bereš lahko recimo tako, da postaviš kazalec na določeno lokacijo v pomnilniku, ki te zanima, potem pa prebereš vrednost, na katero kaže ta kazalec.
Primer:
Koda: |
int data1;
int data2;
int * pData = 0x8000;
data1 = *pData; // data1 sedaj vsebuje kopijo vrednosti pomnilnika na lokaciji 0x8000
pData++; // povečaj vrednost kazalca, da kaže na lokacijo 0x8004
data2 = *pData; // data2 sedaj vsebuje kopijo vrednosti pomnilnika na lokaciji 0x8004
|
Z USB komunikacijo ti žal ne znam pomagati, se nisem še resno ukvarjal s tem na LPC-jih.
~ Aleš |
|
Nazaj na vrh |
|
 |
NeoTO Član


Pridružen-a: Pon 28 Mar 2005 19:19 Prispevkov: 2752 Aktiv.: 11.59 Kraj: Trzic
|
Objavljeno: Ned Jan 11, 2009 4:36 pm Naslov sporočila: |
|
|
Če želiš povečati velikost USB paketkov, moraš najprej spremeniti deskriptorje v datoteki usbdesc.c. Nato moraš povečati še polje, ki je definirano v Keilovem primeru za USB buffer. Ostane ti še popravek velikosti paketkov, ki jih želiš sprejet v usbuser.c. Mislim da je to to.
Zastonj software-a za komunikacijo s HIDom nisem našel (vsaj ne kakšnega v obliki terminala ali podobno). Najdeš pa primere, kako napisat takšen program na tej strani: http://www.lvr.com/usbc.htm. _________________ Lp,
Matevž |
|
Nazaj na vrh |
|
 |
strobos Član

Pridružen-a: Sre 24 Sep 2003 12:19 Prispevkov: 726 Aktiv.: 3.06 Kraj: Brežice
|
Objavljeno: Tor Jan 13, 2009 4:14 am Naslov sporočila: |
|
|
Ob temle:
int YEAR_flash, DOY_flash;
int *pLeto = 0x7000;
int *pDan = 0x8000;
mi javi napako:
demo.c(15): error: #144: a value of type "int" cannot be used to initialize an entity of type "int *"
Kaj sem naredil narobe?
Lp |
|
Nazaj na vrh |
|
 |
alessio Član

Pridružen-a: Pon 04 Dec 2006 8:39 Prispevkov: 363 Aktiv.: 1.60 Kraj: Ljubljana
|
Objavljeno: Tor Jan 13, 2009 6:01 am Naslov sporočila: |
|
|
Popravi v sledečo obliko:
Koda: |
int YEAR_flash, DOY_flash;
int *pLeto = (int *)0x7000;
int *pDan = (int *)0x8000; |
|
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 7 dni
Powered by phpBB © 2001, 2005 phpBB Group
|