2

I am programming msp430 with IAR EBW.

I got the expression as follows:

adres = (uint_fast16_t *) 0x8602 + (0x0200*i);

in a for loop so that i increases with every loop. For some reason it skips every one of two adresses and gives me:

0x8602
0x8A02
0x8E02

and so on. So 0x8802 is skipped, as is 0x8C02 and so on..

Why is that happening?

//// below is full code, note that i is placed in three loops, and everyone gives the same result. //// note also that when check during debugging it shows as: 1,2,3... etc

#include "io430.h"
#include <stdint.h>

int main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  // Inicjalizuj piny GPIO
  P3OUT &= ~(BIT4+BIT5);        // zeruj wartości by zapobiec krótkotrwałym impulsom
  P3DIR |= BIT4; // ustaw pin3.4 UCA0TXD oraz piny 3.0 CS, 3.1 SIMO, 3.3 CLK jako wyjście
  P3DIR &= ~(BIT5);               // ustaw pin3.5 UCA0RXD oraz 3.2SOMI jako wejście
  P3SEL |= BIT4+BIT5;         // daj funkcje TXD i RXD pinom 3.4 i 3.5, funkcje SIMO,SOMI,CLK pinom 3.1,3.2,3.3

  // Inicjalizuj ustawienia zegarów BCS
  BCSCTL1 = CALBC1_16MHZ;       // ustawia DCO na 16MHz, wyłącz XT2, LFXT1 w trybie niskiej częstotliwości
  DCOCTL = CALDCO_16MHZ;        // ustawia DCO na 16MHz
  BCSCTL2 |= BIT2;              // ustawia dzielnik SMCLK na 4

  // Ustaw flash na czyszczenie segmentów
  while(FCTL3&BIT0);            // czekaj aż będzie można inicjalizować
  FCTL2 = FWKEY + BIT6 + BIT5+BIT3+BIT2; // ustawia źródło zegara na MCLK oraz jego dzielnik dający f = 363 kHz
  FCTL1 = FWKEY + BIT1;         // czyść indywidualne segmenty
  FCTL3 = FWKEY;            // zdejmuje blokadę na pisanie i czyszczenie (tu segmentów)

  // Czyść segmenty  
  uint_fast16_t *adres;
  uint_fast8_t i=0;
  for ( i=0 ; i < 59; i++)
    {
      adres = (uint_fast16_t *) 0x8602 + i*0x0200; // ustawia wskaźnik na kolejne miejsa w pamięci. sprawdzić!!
      *adres = 0;               // wyczyść segment przez wpisanie w jego komórkę głupiego bitu
      while(FCTL3&BIT0);        // poczekaj aż generator czasowy dla flasha
    }
  FCTL1 = FWKEY;                // blokuje możliwość czyszczenia

  __delay_cycles(65000);

  // Ustaw flash na zapis danych
  while(FCTL3&BIT0);            // czekaj aż będzie można pisać
  FCTL1 = FWKEY + BIT6;         // pozwól pisać do flash

  // Pisz do flash
  uint_fast16_t szesnastka = 0;

  for ( i=0 ; i < 59; i++)
    {
      szesnastka = (0x55 << 8 ) | 0xF0;
      adres = (uint_fast16_t *) 0x8602 + (0x0200*i); // ustawia wskaźnik na kolejne miejsa w pamięci. sprawdzić!!
      *adres = szesnastka;               // wyczyść segment przez wpisanie w jego komórkę głupiego bitu
      while(FCTL3&BIT0);        // poczekaj aż generator czasowy dla flasha
    }
  FCTL1 = FWKEY;                // blokuje możliwość pisania
  FCTL3 = FWKEY + LOCK;         // ustawia blokadę na pisanie i czyszczenie


  __delay_cycles(65000);


  // Inicjalizuj ustawienia do transmisji UART
  UCA0CTL0 = 0x00;              // ustawia domyślne parametry protokołu
  UCA0CTL1 |= BIT7+BIT6;        // ustawia źródło sygnału na SMCLK
  UCA0BR0 = 0xA0;               // ustawia dzielnik 4MHz do baud rate 9600
  UCA0BR1 = 0x01;               // ustawia dzielnik 4MHz do baud rate 9600                  
  UCA0MCTL |= BIT2+BIT3;        // ustawia modulacje zegara do baud rate 9600

  UCA0CTL1 &= ~UCSWRST;         // włącza maszynę USCI

  uint8_t *ptr;

  // Wyślij wszystkie wyniki poprzez UART
  for( i=0 ; i < 59 ; i++  )
  {
  ptr = (uint8_t *) 0x8602 + i*0x0200; // ustawia wskaźnik na kolejne miejsa w pamięci. 
  while(!(IFG2&UCA0TXIFG));   // czeka na możliwość wysłania
  UCA0TXBUF = *ptr;         // wysyła dane przez UART

  ptr++;
  while(!(IFG2&UCA0TXIFG));   // czeka na możliwość wysłania
  UCA0TXBUF = *ptr;         // wysyła dane przez UART
  }


  return 0;
}
maciejko'
  • 21
  • 2
  • Could you show us the actual loop? `i` might be modified inside it somewhere ... – AntonH Jan 27 '14 at 23:47
  • Wheres i coming from. Could you show the entire loop? – Ron Jan 27 '14 at 23:48
  • You got it, thanks for your replies! – maciejko' Jan 27 '14 at 23:55
  • It's worth adding that the size of `uint_fast16_t` is not necessarily 16 bits anyway. In ``, the *fastest* integer types (`int_fastN_t` or `uint_fastN_t`, where `N`=8, 16, 32 or 64) are defined as [having *at least* `N` bits](http://www.qnx.org.uk/developers/docs/6.5.0/topic/com.qnx.doc.dinkum_en_c99/stdint.html#int_fast8_t). – r3mainer Jan 28 '14 at 00:03
  • Yes I agree with you Sir. I write it in this way to get used to it. Although my CPU is 16bit so if `uint_fast16_t` is considered to have at least 16 bits, and my CPU has 16bits this is the result. Thanks for the link – maciejko' Jan 28 '14 at 00:12

4 Answers4

6

You are casting the first value as a pointer to 16 bit values, so adding 0x200 is going to move it forward 512 16 bit (or 2 byte) values.

If you did:

adres = (uint_fast32_t *) 0x8602 + (0x0200 * i ) ;

It would do:

0x8602
0x8E02
0x9202

Either scale by half, or do the math before the cast:

adres = ( uint_fast16_t *) ( 0x8602 + ( 0x0200 * i ) ) ;
woolstar
  • 5,063
  • 20
  • 31
2

It is pointer arithmetic, not integer math.

As i increments, (uint_fast16_t *) 0x8602 + (0x0200*i) goes up by 0x0200*2 as sizeof(uint_fast16_), in this case, is 2.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

When you do pointer addition, you are adding the size of the pointer's type to the pointer you are operating on. So, for example, adding 1 to a char* will add 1, and adding 1 to a uint32_t* will add 4.

Therefore, I think your code might work as you expect if you change it to:

adres = (uint_fast16_t *) ((char*)0x8602 + (0x0200*i));
mpontillo
  • 13,559
  • 7
  • 62
  • 90
1

You are incrementing a uint_fast16* pointer by 0x0200*i.

When you add to a pointer it increments by the size of the base type so you are incrementing by 2 bytes * 0x0200*i, not just 0x0200*i

tletnes
  • 1,958
  • 10
  • 30