Renesas RX210, kul men tröttande!

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Renesas RX210, kul men tröttande!

Inlägg av Icecap »

Har påbörjat ett projekt med en Renesas RX210 µC. Jag är rimligt nöjd med den, tanken är att den ska ersätta en "gammal" Fujitsi MB90F583CB som är en 16-bitars på max 16MHz. Gamla kretsen tuggar på ganska duktigt osv. men efter skalvet i Japan är tillverkningen skakig och priset högt.

Så nu är det vald en Renesas Rx210 istället. Det är en 32 bitars med en massa(!) godis inbyggd, den tuggar iväg med upp till 50MHz (intern osc. på 32, 36,864, 40 och 50MHz) vilket jag tycker räcker fint, speciellt eftersom den "gamla" 16-bitaren på 16MHz klarade samma jobb utan att svettas allt för mycket. Såklart kan den en massa med externa kristaller, PLL osv. men jag ämnar att använda den interna 32MHz klocka, den räcker långt.

Men nu kommer det roliga...

Många funktioner ger många register! Hårdvaramanualen är bara på 1612 sidor, det finns säkerhetsregister som man måste "öppna" med specifika värden för att kunde skriva i vissa vitala delar. Och jag har nu suttit 2 dagar med att öppna en satans serieport!!! Nu är jag i mål. Man ska:
* Sätta portpinnarna rätt (in/ut + startnivå) samt open-drain eller inte, pull-up eller inte osv.
* Sätta portpinnerna till att fungera med deras alternativa funktion (i detta fall UART Tx + Rx). En bit per portpinne.
* Slå av avstängningen av UART'en i "Low Power Consumption"-funktionen, bara en bit i något register. Är dock skyddad av skyddsfunktionen varför man får öppna den först, ändra och låsa efter sig.
* Sätta UART'en till rätt typ (Asynk, n81, baudrate osv.) En uppsjö av I2C, SPI, Smart Card, Async. och andra funktioner gör att det är en hel del register att ställa rätt för detta.
* Sedan ska "Multi-Function Pin Controllern" ställas rätt (et register per portpinne!)
* Interruptnivåer väljas, läggas in, enablas/disablas osv.

Tro mig, jag höll på att bli mer skvatt galen än jag redan är. Renesas är bra på att tillverka häftiga kretsar men i tydlighet och hjälp i databladet är de på nivå med Atmel. Inte imponerande alltså.

Men nu har jag grejen liggande bredvid mig, jag har kopplat två serieporta på den samt 3 st LED och den gör som den får besked på. Programmeringen fungerar bra med HEW (Renesas IDE + kompiler), jag skulle dock gärna vilja ha den till att fungera i Eclipse och KPIT GNU-kompilern men det får jag lägga kraft på senare.

Jag ska också viderutveckla mitt Flash-program till den, det fungerar redan på Renesas M16Coch fungerar via den inbyggda (från fabriken) bootloader samt handskakningssignalerna i serieporten. Då kan jag välja att aktivera en terminalfunktion i det program då jag ju redan använder en vanlig UART att programmera via.

Totalen är att mitt flashningsprogram kan övervaka HEX-filen datum/tid, om den ändras inaktiveras terminalfunktionen, kretsen resettas och snäpps in i bootloder-läget, programmet överförs varefter terminalfunktionen återaktiveras om man har vald detta. MYCKET smidigt vid utveckling och debuggning!

Men satan i gatan vad krångligt det har varit att få gång i den första serieport! Att få gång i nästa serieport tog 3 minuter, nu vet jag ju hur man gör...

Att jag har vald just RX210 är för att den kan drivas med 5V. Detta ger mer störimmunitet och i de miljöer som projektet kan komma att användas i är det en kännbar fördel.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Renesas RX210, kul men tröttande!

Inlägg av mri »

Jag känner med dig! :-)
Att lära sig en ny processor är JOBBIGT. När det gäller Renesas kan jag väl tycka att databladen språkligt ibland är undermåliga. Men hårdvaran har vettiga defaults och oftast tycker jag saker brukar fungerar någolunda även på första eller andra försöket när man konfat bitarna efter bästa förmåga. (Har plöjt igenom två 16-bitars R8C modeller.)
Har kämpat med en CC2430 (?) processor från TI och där kan jag inte säga samma sak! I den måste varenda sketna bit vara absolut rätt för att något överhuvudtaget skulle röra på sig.

Håller för tillfället på att plöja ner i en ARM Coretex-M4 och det tar tid. Hobbyprojekt så det får ta tid. Fick igång SPI ikväll. Avancerad processor med coola features, men också lika avancerad att konfa och lära sig.

Man byter inte processor så där bara.
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Renesas RX210, kul men tröttande!

Inlägg av Icecap »

mri: Jag har kört en del andra projekt med Renesas M16C i olika tappningar, allt från M16C-62 till M16C-26A och visst, de kan vara lite intressanta i vissa delar rörande databladet och "interagerande" med andra delar som kan vara svåra att överskåda - men RX-serien tar priset!

Å andra sidan får jag ju respektera att den kör med 50MHz och drar runt 20mA för µC själv. En '386 på 50MIPS med FPU lär knappast klara sig med den ström!
SvenW
Inlägg: 1156
Blev medlem: 24 april 2007, 16:23:10
Ort: Göteborg

Re: Renesas RX210, kul men tröttande!

Inlägg av SvenW »

Jag trodde att onödig komplexitet var karakrtäristiskt för Amerikanska grejer. Tydligen ännu värre med Japanska.
Hoppas bara inte Kineserna tar över och slår rekord!
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Renesas RX210, kul men tröttande!

Inlägg av Icecap »

Nu vet jag ju inte vad du menar med "onödig komplexitet" men när antalet interruptvektorer når 250 st, interrupt nivåer når 15 st (+ inaktiv) samt att många pinnar kan ha fler olika funktioner samtidig, då kan jag förstå att det är många saker som ska ställas rätt.

Men just nu känns det som lite väl många saker på en och samma gång! Och jag har redan hittat ett fel i kompilerns data...

EDIT: Jahopp, helgen har gått åt... Men nu har jag en time-tick med interrupt, jag har en seriell port som sänder interrupt-driven. Jag mätte lite för att ha lite argument inför ett par Ex-jobbare som är med i detta.

Att överföra 34 tecken med 9k6n81 tar en tid. Att skriva ut dom tar en tid. Men förhållandet är så att om det tar 1 tidenhet att skriva ut datan och peta i buffer tar det 232 gångar så lång tid att sända skiten! Och då har jag räknat med overheaden vid interrupten!

Nu där jag är lite mindre osams med RX210'an börjar det vara lite kul att klämma in lite hastighet och göra grejer. Den har tydligen lite DSP-funktioner, det finns exempelkod för FFT osv.
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Renesas RX210, kul men tröttande!

Inlägg av Icecap »

Åh ja, jag börjar trivas bättre med RX'en faktisk. Håller på att lägga in den i ett par design, ett av dom är bara byte av µC för att få en som tillverkas, den gamla modell slutade tillverkas efter skalvet i Japan.

På jobbet har vi ju LED-moduler, jag testade med två stycken á 32 x 16 punkter, 10 mm mellan pixlarna och varje pixel består av en röd, en grön och en blå LED. Data skickas in synkront, alltså Data till pinnar (RGB för övre och undre halvan) och sedan skaka klockan. När alla data i skanningsraden är överförd skakar man på strobe och data visas. Såklart är modulerna med tätning och gjorda för att bygga stora ytor av, vi pratar dessa arena-videoskärmar...

Jag hade ett helvete med att få PWM-funktionen att fungera, Renesas må vara bra på att göra bra och ganska billiga kretsar - men de är inte lika bra på datablad! Jag fick det dock att fungera, därmed kan jag ställa intensiteten på dessa LED-moduler. Just de moduler jag "leker" med är lite "billiga", det finns inte drivkretsar för alla LED, man måste skanna 4 rader. Men en timer-interrupt löste detta och att välja bildminne, klocka ut 128 bytes data, styra radräkningen och allt för en rads uppdatering tar 252µs - och jag har inte trimmat programmet.

Just detta att byta rad gav lite ghosting och jag insåg att jag skulle bli tvunget att styra PWM-delen också för att släppa detta. Men nej! Jag kom på att Renesas har vald ett lite konstigt sätt att styra vad varje pinne gör. Det finns ett register för om en portpinne ska vara in eller ut, inget konstigt i det.
Sedan ska man välja om portpinnen ska vara portpinne eller om den ska användas till den alternativa funktion.
Sedan måste man välja vilken alternativ funktion den ska ha (jupp, ett register per portpinne!) och då börjar det bli lite tråkigt att skriva. Dock är databladet rimligt tydligt på den punkt.

Men det gav mig lösningen på ghost-problemet! Jag satte portpinnens output-register till '1' (= display av) och precis innan skanningen byter rad byter jag portpinnen från alternativ funktion till portpinne, detta växlar pinnens signal från PWM (med lysintensiteten) till "display av", sedan läggs rätt radnummer in, data latchas ut till drivstegen och portpinnen återställs till att fungera som PWM-utgång. Resultat: totalt ghost-fri!

Nu trilskas det lite med sändning av UART-data. Jag vill ha en interruptstyrd buffring av sändning av data men jag måste kolla lite mer på hur jag ska styra enable & disable av interrupten, det finns ett par möjligheter och jag ska hitta den rätta. Som det är nu hakar det upp sig ibland och jag är tveksam till om jag har programfel, samma teknik har jag använd på en del andra processorer utan problem - men med RX'en finns det fler olika möjligheter att disabla & enabla interrupten och jag har någon känsla av att jag använder fel typ.

Men jag har hittat en Application Note med ett exempel som jag ska lusläsa.

Jag hittade även ett par bortkastade LED-moduler. Ett var en monokrom som hade blivit brutalt påkörd (satt i ett höjdvarningsdisplay) och det var knäckt. Men drivkretsarna fanns kvar, alltså fram med varmluftpistolen och ta dom med hem, jag har sedan tidigare ett antal trasiga plattor som jag ska laga och nu har jag reservdelar.

Andra plattan var en 16 x 16 RGB med pixelavstånd om 12mm. Felet på den är att ett par gröna LED lyser svagt på en punkt. Ska testa att byta drivkrets vid tillfälle men just nu använder jag den för att testa lite grejer. Jag testade att kräma på med alla LED i alla 16 x 16 punkter tända samtidig (fast det blir bara 16 x 8 då displayen multiplexas i två halvor). Min nätdel kan bara ge 3A så den gick i knä vid 56% intensitet... Och ja, det ger ljus!

Det är kul att leka!
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Renesas RX210, kul men tröttande!

Inlägg av Icecap »

Då så, lite statusrapport:
A) Interruptstyrd seriell sändning fungerar bra! Men Renesas är lite konstiga där: det saknas en bit som man kan kolla huruvida UART'ens sändregister är ledigt eller inte! Jag har dock löst detta och det var inget svårt när jag väl hade gjort det.

Kod: Markera allt

Lite definitioner som kan abstrahera från hårdvaran på ett mer lättläst sätt:
#define SER1_Tx_Pin     PORT2.PODR.BIT.B6
#define SER1_Tx_Pin_Dir PORT2.PDR.BIT.B6
#define SER1_Rx_Pin     PORT3.PIDR.BIT.B0
#define SER1_Rx_Pin_Dir PORT3.PDR.BIT.B0

Först en struktur som håller lite buffer osv. till serieporten. Läget är helt vanlig asynk.
struct
  {
  struct
    {
    char            Buffer[500];
    volatile _UINT  In;
    volatile _UINT  Out;
    volatile _UINT  Busy;
    volatile _UBYTE Overflow;
    } Tx;
  struct
    {
    char Buffer[500];
    volatile _UINT In;
    } Rx;
  } Ser1;

Sedan ska skiten initieras:
void Initiate_Ser_1(void)
  {
  _UINT Ctr;
  SER1_Rx_Pin_Dir    = false;  // Set SER1 Rx direction as input
  SER1_Tx_Pin_Dir    = true;   // Set SER1 Tx direction as output
  SER1_Tx_Pin        = true;   // Set SER1 Tx start position ('1')
  Ser1.Tx.In         = 0;      // Set to initial state
  Ser1.Tx.Out        = 0;      // Set to initial state
  Ser1.Tx.Busy       = false;  // Set to initial state
  Ser1.Rx.In         = 0;      // Start position
  Ser1.Rx.Buffer[0]  = false;  // Just for the sake of nothing
  Ser1.Tx.Overflow   = false;  // Unmark it for starter
  SYSTEM.PRCR.WORD   = 0xA502; // Open the lock
  MSTP(SCI1)         = 0;      // Power up SCI1
  SYSTEM.PRCR.WORD   = 0xA500; // Lock up again
  SCI1.SCR.BYTE      = 0x00;   // Shut off all settings
  SCI1.SCR.BYTE      = 0x00;   // Shut off all settings
  SCI1.SMR.BYTE      = 0x00;   // Async, 8n1, PCLKB : 1
  SCI1.SCMR.BYTE     = 0xF2;   // Not Smart Card Interface mode
  SCI1.SEMR.BYTE     = 0x00;   // No noise filter, Async base = 16 clk
  SCI1.SIMR1.BYTE    = 0x00;   // To enable the writing of SCR.RE & TE
  MPC.PWPR.BYTE      = 0x00;   // Start allowing writing
  MPC.PWPR.BYTE      = 0x40;   // Allow writing to MPC-registers
  MPC.P26PFS.BYTE    = 0x0A;   // Select TX1D on P26 
  MPC.P30PFS.BYTE    = 0x0A;   // Select RXD1 on P30
  MPC.PWPR.BYTE      = 0x80;   // Shut down writing to MPC-registers
  SCI1.BRR           = ((PCLK / BAUD_RATE) / 32) - 1;
  for(Ctr = 0; Ctr <= (CPU_CLK / 2) / BAUD_RATE; Ctr++); /* 1bit+ time wait */
  SCI1.SCR.BYTE      = 0x30;   // Enable Tx & Rx, stops most writings also
  SCI1.SCR.BYTE      = 0xF0;   // Enable RXI
  PORT2.PMR.BIT.B6   = 1;      // Use SER1 Tx as peripheral function
  PORT3.PMR.BIT.B0   = 1;      // Use SER1 Rx as peripheral function
  IPR(SCI1, )        = 1;      // Interrupt priority to lowest active
  IR(SCI1,RXI1)      = false;  // Clear any residual interrupt
  IR(SCI1,TXI1)      = false;  // Clear any residual interrupt
  IR(SCI1,ERI1)      = false;  // Clear any residual interrupt
  IR(SCI1,TEI1)      = false;  // Clear any residual interrupt
  IEN(SCI1,RXI1)     = true;   // Enable Rx Interrupt to exist
  IEN(SCI1,TXI1)     = true;   // Enable Tx Interrupt to exist
  IEN(SCI1,ERI1)     = true;   // Enable Rx error Interrupt to work - or not
  IEN(SCI1,TEI1)     = false;  // Enable Interrupt to work - or not
  }

Sedan lite interrupts:
#pragma interrupt SCI1_Tx_ISR(vect=VECT(SCI1,TXI1))
void SCI1_Tx_ISR(void) // Ger en interrupt när den börjar sända nästa tecken - om interrupt är enablad
  {
  if(Ser1.Tx.Busy)
    {
    SCI1.TDR = Ser1.Tx.Buffer[Ser1.Tx.Out]; // Slam out the next byte to send
    if(++Ser1.Tx.Out >= sizeof(Ser1.Tx.Buffer)) Ser1.Tx.Out = 0; // Update Out-index, circular buffer
    if(Ser1.Tx.In == Ser1.Tx.Out)
      { // They are same, end further transmission
      Ser1.Tx.Busy   = false; // Set to done
      IEN(SCI1,TXI1) = false; // Stop further interrupts as of now
      }
    }
  }


#pragma interrupt SCI1_Rx_ISR(vect=VECT(SCI1,RXI1))
void SCI1_Rx_ISR(void)
  {
  // Recieve interrupt (if enabled)
  _UBYTE Incoming;
  Incoming = SCI1.RDR; // A read empties the Rx-buffer and removes the interrupt
  if(Ser1.Rx.In < sizeof(Ser1.Rx.Buffer) - 1)
    { // Room exists, put in buffer
    Ser1.Rx.Buffer[Ser1.Rx.In++] = Incoming;
    }
  }


#pragma interrupt SCI1_ERI_ISR(vect=VECT(SCI1,ERI1))
void SCI1_ERI_ISR(void)
  { // Rx error interrupt
  SCI1.SSR.BYTE = (SCI1.SSR.BYTE & 0xC6) | 0xC0; // Clear Rx error
  }


#pragma interrupt SCI1_TEI_ISR(vect=VECT(SCI1,TEI1))
void SCI1_TEI_ISR(void)
  {
  // Transmit ended interrupt. Usefull with RS485 communication
  IR(SCI1,TEI1) = 0; // Acknowledge interrupt
  }
Men det man sänder ska ju petas i sänd-buffern och det var största problemet ett tag. Det är numera löst:

Kod: Markera allt

void Send_Serial_Byte(_UBYTE Data)
  {
  volatile _UINT Next;
  if(SCI1.SSR.BIT.TEND || (IR(SCI1,TXI1)  && !Ser1.Tx.Busy)) // OK, room exists, slam it out
    {
    IR(SCI1,TXI1) = 0;    // Clear possibel pending interrupt
    SCI1.TDR      = Data; // Just dunk it out, room exists!
    }
  else
    {
    // Use overrun protection
    Next = Ser1.Tx.In + 1; // Check if overrun is imminent
    if(Next >= sizeof(Ser1.Tx.Buffer)) Next = 0; // Circular buffer, remember?
    while(Next == Ser1.Tx.Out) Ser1.Tx.Overflow = true; // Mark that overflow was threatning while waiting
    // Overrun protection done, now buffer the datas
    IEN(SCI1,TXI1)             = false; // No interrupts just now
    Ser1.Tx.Busy               = true;  // Mark as using buffering mode
    Ser1.Tx.Buffer[Ser1.Tx.In] = Data;  // Put data into buffer
    Ser1.Tx.In                 = Next;  // Already calculated, reuse that
    IEN(SCI1,TXI1)             = true;  // Allow interrupts to come
    }
  }


void Send_Serial_Buffer(_UBYTE* Data)
  {
  while(*Data)
    {
    Send_Serial_Byte(*(Data++));
    }
  }
För att sända ett tecken (en byte) på serieporten kallar jag alltså Send_Serial_Byte(). För att skriva ut en sträng/text använder jag Send_Serial_Buffer() som bara skickar tecken efter tecken.

Och varför då så besvärligt? Helt enkelt för att spara tid! Kör man 9600n81 tar varje byte 10 bits tid att sända, alltså 960 tecken/sekund. Ganska bra hastighet - men om µC'n tuggar på med den interna klocka på 50MHz blir det 52083 instruktioner som, utan interruptstyrd sändning och buffring, kastas bort... per tecken! Det overhead som hela interruptgrejen ger tjänar jag enkelt hem i hastighet.

Skulle jag försöka överfylla buffern kommer den att stanna upp och vänta till det blir plats att peta i varje tecken, samtidig sätts flaggan (Ser1.Tx.Overflow) så att man kan kolla det om det behövs. Den flagga nollas bara vid initieringen.

Principen för denna buffring har jag använd genom många år på många olika processorer - men alla andra har haft en flagga som indikerar om sänd-registret är redo att ta emot ny byte eller inte och just på denna µC fattas det tydligen.


B) PWM är inte tydligt beskrivit i databladet. Det förklaras att man kan sätta startvillkor men vad som ska hända sedan är en lita tuffare nöt att få veta, jag gissade till slut och fattade.

Kod: Markera allt

Först abstrahera lite:
#define Display_Pin_13    PORTB.PODR.BIT.B5 /* Pin 55, MTIOC2A, cable pin 13 */
#define Display_Pin_13_F  PORTB.PMR.BIT.B5  /* The mode bit */
#define DISPLAY_PWM_STEPS 100 /* 0-100% */

void Initiate_Display_PWM(void)
  {
  SYSTEM.PRCR.WORD   = 0xA502; // Open protection
  MSTP(MTU2)         = 0;      // MTU2 module stop state cancelled
  SYSTEM.PRCR.WORD   = 0xA500; // Lock it again!
  MPC.PWPR.BIT.B0WI  = 0;      // Enable writing PFSWE bit
  MPC.PWPR.BIT.PFSWE = 1;      // Enable writing PFS register
  MPC.PB5PFS.BYTE    = 1;      // Use PB5 as MTIOC2A, no interrupt used
  MPC.PWPR.BIT.PFSWE = 0;      // Disable writing PFS register
  MPC.PWPR.BIT.B0WI  = 1;      // Disable writing PFSWE bit
  Display_Pin_13_F   = 1;      // Set port pin alternative function
  Display_Pin_13     = 1;      // Set för blanking purpose in scanning
  // Now the port pin should be prepared to use
  MTU2.TCR.BYTE      = 0x20;   // PCLK/1, Count on rising edge, TCNT cleared @ TGDA-match
  MTU2.TMDR.BYTE     = 0x02;   // PWM mode 1, TGRA-TGRD operates normally
  MTU2.TIOR.BYTE     = 0x12;   // Initial low, High on Compare Match
  MTU2.TGRA          = DISPLAY_PWM_STEPS * DISPLAY_PWM_RESOLUTION; // PWM Cycle time
  MTU2.TGRB          = DISPLAY_PWM_STEPS * (DISPLAY_PWM_RESOLUTION - Display.Light); // PWM compare register
  MTU.TSTR.BYTE      = 0x04; // Let MTU2 run
  } 
Stötestenen var värdet som skrivs i MTU2.TIOR.BYTE. I databladet anges bara låga nibblens funktion men jag testade fram att den höga nibbel avgör vad som händer sedan när rätt räknavärde uppnås.

För att ställa PWM-värdet:

Kod: Markera allt

void Display_Set_Light(_UINT Value)
  { // This routine controls the intensity on teh display. '0'= LIGHT ON! '1' = Display off!
  if(Value > DISPLAY_PWM_RESOLUTION) Value = DISPLAY_PWM_RESOLUTION;
  MTU2.TGRB = (DISPLAY_PWM_RESOLUTION - Value) * DISPLAY_PWM_STEPS;
  }
För tillfället jobbar jag på att bygga ett PONG-spel på 2 st moduler med 32 * 16 RGB-pixlar, jag har redan full funktion på scanningen, displayminnet, pixel-ritning, linje-ritning osv. så nu är det själva PONG-reglerna med poängräkning som gäller. Man kommer att styra paddlarna med var sin potentiometer, då kan jag testa den inbyggda AD-omvandlaren (12 bit) och få den att fungera.

C) En systemtimer är alltid bra att ha!

Kod: Markera allt

void Initiate_System_Timer(void)
  {
  Timer_Tick          = 0;
  Hour                = 0;
  Minute              = 0;
  Second              = 0;
  Second_Update       = 0;
  Prescaler           = 0;
  Delay_Counter       = 0;
  SYSTEM.PRCR.WORD    = 0xA502;
  MSTP(CMT0)          = 0;      // Timer module stop state cancelled
  SYSTEM.PRCR.WORD    = 0xA500; // Lock up again!
  CMT.CMSTR0.BIT.STR0 = 0;      // Stop timer
  CMT0.CMCR.WORD      = 0x0042; // Enable compare interrupt & set PCLK:128
  CMT0.CMCNT          = 0x0000; // Clear the count
  CMT0.CMCOR          = (PCLK / 128) / TIME_TICK;  // Should give 100Hz a.k.a. 10ms
  IPR(CMT0,CMI0)      = 2;      // Interrupt priority = 2
  IEN(CMT0,CMI0)      = 1;      // Enable interrupts
  CMT.CMSTR0.WORD     = 0x0001; 
  } 

#pragma interrupt CMT0_ISR (vect=VECT(CMT0,CMI0))
void CMT0_ISR(void) // System timer interrupt
  {
  Timer_Tick++; // Just a 10ms timer for ...well some... use
  if(++Prescaler >= 100) // One second gone
    {
    Prescaler = 0;
    Second_Update++;
    if(++Second >= 60) {Second = 0; if(++Minute >= 60) {Minute = 0; Hour++;}}
    }
  if(Delay_Counter) Delay_Counter--;
  #define DOUBLE_BLINK_OFFSET 10 /* Eq. 0,1 sec */
#if true
  // Hey man, a blinking blue LED is cool!
  switch(Prescaler)
    {
    case 0:
      LED_Blue = true;
    break;
    case 1:
      LED_Blue = false;
    break;
  #if DOUBLE_BLINK_OFFSET
    case DOUBLE_BLINK_OFFSET:
      if(Main_Normal) LED_Blue = true;
      Main_Normal = false;
    break;
    case DOUBLE_BLINK_OFFSET + 1:
      LED_Blue    = false;
    break;
  #endif // DOUBLE_BLINK_OFFSET
    }
#endif
  }
Om variabeln "Main_Normal" ställs till icke-noll i main-loop kommer det att bli en dubbel-blink vilket gör att jag kan se om main-loop har hängt sig. Utan den blir det enkelblink.
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Renesas RX210, kul men tröttande!

Inlägg av mri »

Den här processorn har alltså ingen hårdvaru FIFO heller? Verkar vara standard för Renesas att inte ha det... Iofs inget problem i ditt fall med 50MHz och 9600bps. Du har antagligen DMA grejs på den där som kan hängas på serieporten också, ifall du inte vill reagera på varje enskillt tecken.

Jag kör 125 kbps på en 20 MHz Renesas utan hårdvaru FIFO och där måste man hela tiden passa på att inte hålla interrupten avstängda för länge så att man tappar tecken i kommunikationen.
Har jobbat med en ARM7 processor som hade 16 byte Tx och Rx FIFO. Betydligt lugnare med kommunikations interrupt där. Processorn kan då istället syssla med det verkliga arbetet.
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Renesas RX210, kul men tröttande!

Inlägg av Icecap »

Nja... 1 stegs FIFO är inte mycket att skryta med faktisk.

Å andra sidan har man 15 interruptprioriteter att jobba med och man kan välja en interruptvektor som "snabb respons". 125kbps ger vid synkron överföring ändå 3200 instruktioner vid 50MHz CPU-klocka vilket är högsta frekvensen på den interna oscillator.

Är det asynkron överföring ger det ändå 4000 instruktioner vilket borde vara rikligt med tid.

Men är det hastighet som gäller kan det vara dags att fundera på att använda DMA-funktionaliteten som finns, det kräver dock att man vet storleken på blocket som ska tas emot eller sändas.
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Renesas RX210, kul men tröttande!

Inlägg av blueint »

Hur är det med möjligheterna att trigga så att en DMA skickar in nästa tecken istället för att en interruptrutin sköter det?
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Renesas RX210, kul men tröttande!

Inlägg av mri »

Problemet är inte att hinna serva kommunikationen, om kommunikation var det enda processorn behöver göra. Problem uppstår i mitt fall om någon annan aktivitet behöver stänga av interrupten i mer än 80 us, då tappar kommunikationen tecken och det leder till omsändningar. Eller rättare sagt, allt måste byggas så att interrupten inte behöver stängas av nån längre stund. T.ex. för att få till rätt väntetider till en simpel DS18s20 fick jag bygga en timerstyrd schedulerare.

Vad gäller DMA hade CC2430 processorn intelligent sådan. Den kunde t.ex. tolka första inkommande byte som längd på blocket. Testade aldrig denna funktion dock, men det borde vara möjligt att bygga meddelande sändning och mottagning som nästan helt jobbade i bakgrunden utan hjälp av interruptrutiner.
Användarvisningsbild
Icecap
Inlägg: 26650
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Renesas RX210, kul men tröttande!

Inlägg av Icecap »

Jo, 80µs är inte lång tid... Vid 20MHz blir det bara 1600 CPU-steg.

Jag kollade just databladet och RX'en kan detta med DMA på serieport 5.
Skriv svar