www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

LPC2148 USB, IAP in RTC

 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
strobos
Član
Član



Pridružen-a: Sre 24 Sep 2003 12:19
Prispevkov: 726
Aktiv.: 3.06
Kraj: Brežice

PrispevekObjavljeno: Ned Jan 11, 2009 12:23 am    Naslov sporočila:  LPC2148 USB, IAP in RTC Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
alessio
Član
Član



Pridružen-a: Pon 04 Dec 2006 8:39
Prispevkov: 363
Aktiv.: 1.60
Kraj: Ljubljana

PrispevekObjavljeno: Ned Jan 11, 2009 12:22 pm    Naslov sporočila:  Re: LPC2148 USB, IAP in RTC Odgovori s citatom

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
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
NeoTO
Član
Član



Pridružen-a: Pon 28 Mar 2005 19:19
Prispevkov: 2752
Aktiv.: 11.59
Kraj: Trzic

PrispevekObjavljeno: Ned Jan 11, 2009 4:36 pm    Naslov sporočila:   Odgovori s citatom

Č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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo MSN Messenger - naslov
strobos
Član
Član



Pridružen-a: Sre 24 Sep 2003 12:19
Prispevkov: 726
Aktiv.: 3.06
Kraj: Brežice

PrispevekObjavljeno: Tor Jan 13, 2009 4:14 am    Naslov sporočila:   Odgovori s citatom

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
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo Pošlji E-sporočilo
alessio
Član
Član



Pridružen-a: Pon 04 Dec 2006 8:39
Prispevkov: 363
Aktiv.: 1.60
Kraj: Ljubljana

PrispevekObjavljeno: Tor Jan 13, 2009 6:01 am    Naslov sporočila:   Odgovori s citatom

Popravi v sledečo obliko:
Koda:
int YEAR_flash, DOY_flash;
int *pLeto = (int *)0x7000;
int *pDan =  (int *)0x8000;
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> ARM arhitektura Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Stran 1 od 1

 
Pojdi na:  
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: 6 dni


Powered by phpBB © 2001, 2005 phpBB Group