Wpis z mikrobloga

Koledzy i koleżanki szybkie pytanko z #programowanie

Mam tablicę :

short int tab_sinus[] = {

0x8000,0x8004,0x8008,0x800c,0x8011,0x8015,0x8019,0x801e,
0x8022,0x8026,0x802a,0x802f,0x8033,0x8037,0x803c,0x8040,
0x8044,0x8048,0x804d,0x8051,0x8055,0x805a,0x805e,0x8062,
0x8066,0x806b,0x806f,0x8073,0x8078,0x807c,0x8080,0x8084,
0x8089,0x808d,0x8091,0x8096,0x809a,0x809e,0x80a2,0x80a7,
0x80ab,0x80af,0x80b4,0x80b8,0x80bc,0x80c1,0x80c5,0x80c9,
0x80cd,0x80d2,0x80d6,0x80da,0x80df,0x80e3,0x80e7,0x80eb,
0x80f0,0x80f4,0x80f8,0x80fd,0x8101,0x8105,0x8109,0x810e,
0x8112,0x8116,0x811b,0x811f,0x8123,0x8127,0x812c,0x8130,
};

I chcę ją wpisać akurat do pamięci SDRAM, niestety weryfikacja jest błędna więc coś jest skopane. Inne dane 16 bitowe są wpisywane ok.

Funkcja :

void writeTab(short int tab[]){

uint32_t i;
volatile uint32_t *wr_ptr;
volatile uint8_t *char_wr_ptr;
volatile uint16_t *short_wr_ptr;

/* 16 bit continuous write */
wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
short_wr_ptr = (uint16_t *)wr_ptr;
_DBG_("ZApis tablicy sinus... ");
for ( i= 0; i < sizeof(tab); i++ )
{
*short_wr_ptr++ = (uint16_t)(tab[i]);

*short_wr_ptr++ = (uint16_t)((tab[i]>>16) & 0xffff); // ???

/* verifying */
wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
short_wr_ptr = (uint16_t *)wr_ptr;
for ( i= 0; i < sizeof(tab); i++ )
{
uint32_t data;

data = ((uint32_t) *short_wr_ptr++) << 0;
data |= ((uint32_t) *short_wr_ptr++) << 16;
if ( data != i ) /* be aware of endianess */
{
/* byte comparison failure */
_DBG_("Blad - tablica sinus!\r\n");
while ( 1 ); /* fatal error */
}
wr_ptr++;
}

}
}
  • 13
On raczej nie generuje wartości ujemnych. Mógłbyś jeszcze wyjaśnić dokładniej ten przytoczony zapis?


@paw39: tab[i] jest typu short int, czyli całkowitego ze znakiem. Short jest z reguły 16-bitowy i zapisany za pomocą kodu uzupełnień do 2, czyli ma zakres wartości od -32768 do 32767. Tutaj prawdopodobnie chciałeś uƶyć unsigned short int.

to jest na procku

No to ten for wykona się dwa razy.
@paw39: PS:


void writeTab(short int tab[])
{
``````
    
**uint32_t i;
    
volatile uint32_t*** wr_ptr;
    
volatile **uint8_t*** char_wr_ptr;
    
volatile **uint16_t*** short_wr_ptr;
``````
    /* 16 bit continuous write */
    wr_ptr = (
**uint32_t***)SDRAM_BASE_ADDR;
    short_wr_ptr = (
**uint16_t***)wr_ptr;
    _DBG_(
"ZApis tablicy sinus... "_);
    
for (i = 0; i < sizeof(tab); i++) {
        *short_wr_ptr++ = (
**uint16_t**)(tab[i]);
``````
        *short_wr_ptr++ = (
**uint16_t**)((tab[i] >> 16) & 0xffff); // ???
``````
        /* verifying */
        wr_ptr = (
**uint32_t
(uint16_t)((tab[i]>>16) & 0xffff);


@paw39: to wyraƶenie jest zawsze równe zero (dzielenie 0-65535 przez 65536 bez reszty a potem bitowy and otrzymanego zera i 65535). Co tutaj chciałeś zrobić?
@KrzaQ2: Powiem szczerze, że nie analizowałem tego, sam jestem ciekawy. Akurat korzystam z przykładu testowego i ten kod poniżej działa ok:

/* 16 bit continuous write */
    wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
          short_wr_ptr = (uint16_t *)wr_ptr;
    _DBG_("Writing in 16 bits continuous format... ");
    for ( i= 0; i < SDRAM_SIZE/4; i++ )
    {
                *short_wr_ptr++ = (uint16_t)(i & 0xffff);
                *short_wr_ptr++ = (uint16_t)((i>>16) & 0xffff);
    }


          /* verifying */
    wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
          short_wr_ptr = (uint16_t *)wr_ptr;
          for ( i= 0; i < SDRAM_SIZE/4; i++ )
          {
            uint32_t data;
``````
                data = ((uint32_t) *short_wr_ptr++) << 0;
                data |= ((uint32_t) *short_wr_ptr++) << 16;
                if ( data != i )        /* be aware of endianess */
                {
                          /* byte comparison failure */
                        _DBG_("Verifying fail, testing terminated!\r\n");
                          while ( 1 );        /* fatal error */
                }
                wr_ptr++;
          }
@KrzaQ2: Jest jeszcze druga opcja dla zapisu z której nie korzystałem:

/* byte comparison succeed. */
          wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
          short_wr_ptr = (uint16_t *)wr_ptr;


          /* Clear content before 16 bit access test */
          for ( i= 0; i < SDRAM_SIZE/4; i++ )
          {
                *wr_ptr++ = 0;
          }
``````
          /* 16 bit write */
          _DBG_("Writing in 16 bits format... ");
          for (i=0; i<(SDRAM_SIZE/4); i++)
          {
                *short_wr_ptr++ = 0x5AA5;
                *short_wr_ptr++ = 0xAA55;
          }
``````
          /* Verifying */
          wr_ptr = (uint32_t *)SDRAM_BASE_ADDR;
``````
          for ( i= 0; i < SDRAM_SIZE/4; i++ )
          {
                if ( *wr_ptr != 0xAA555AA5 )        /* be aware of endianess */
                {
                          /* 16-bit half word failure */
                        _DBG_("Verifying fail, testing termintated!\r\n");
                      while ( 1 );        /* fatal error */
                }
                wr_ptr++;
          }
          _DBG_("OK\r\n");
*short_wr_ptr++ = (uint16_t)(i & 0xffff);

*short_wr_ptr++ = (uint16_t)((i>>16) & 0xffff);


@paw39: ale on tutaj zapisuje i = indeks a nie wartość z tabeli. Ponadto tutaj to ma sens jeśli i jest ≥32-bitowe i moƶe osiągnąć wartości ≥65536 (to zwykłe rozdzielenie wartości na słowo wysokie i niskie)
@KrzaQ2: dokładnie już wiem o co chodzi. Jest to zapis ciągły słów 16 bitowych a komórki są 32 bitowe. Mogę zapisać bez problemu do każdej komórki 32-bitowej wartość 16 bitową tylko to marnotrawstwo. Już poprawiłem i jest OK. ( ͡° ͜ʖ ͡°)