CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

large arrays of single bits - index limitation

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

large arrays of single bits - index limitation
PostPosted: Tue Jan 22, 2008 9:53 am     Reply with quote

Hi.

I've created a large array of single bits (within a union):

Code:
  union changeFlags
    {
    int8 flagByte[66];
    int1 flagBit[528];
    } dmxChange; 



It seems that an int16 pointer won't count past 255. In this code, only the first 256 bits end up changed, regardless of the passed values for startChan and endChan:

Code:
void force_change_flags(int16 startChan, int16 endChan, int1 value)
  {
  int16 i;
  for (i=startChan;i<=endChan;i++)
    {
    dmxChange.flagBit[i] = value;
    }



I really need individual access to 528 elements in this array. Any suggestions?

Thanks!
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Jan 22, 2008 2:09 pm     Reply with quote

Can you tell us why you need to access it in a union, and not just use a function to change a byte/bit ??
Code:
#define FIRM_MINOR  8
#define FIRM_MAJOR 'L'
#define HARD_MAJOR  12
#define HARD_MINOR  07
#include <18F4620.h>
//#include <18F4525.h>
#device adc=8
#fuses hs,wdt32,noprotect,nolvp,put
#use delay(clock=18432000,RESTART_WDT)
#use rs232(baud=19200,xmit=PIN_B3,invert,stream=debug)
#use rs232(xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5,baud=1200,bits=8,parity=e,errors,stream=CIM)
#case
#zero_ram
//========================= Defines ================================//
//========================= Globals =================================//
int8 flagByte[66];
//========================= Prototypes ==============================//
void init(void);
void force_change_flags(int16 startChan, int16 endChan, int1 value);
//========================= Main ====================================//
void main(void)
{
  int16 i,j;
  init();
  i=75;
  j=500;
  force_change_flags(i, j, TRUE);
  force_change_flags(410, 420, 0);
  for(i=0;i<sizeof(flagByte);i++){
    fprintf(DEBUG,"0x%2X,",flagByte[i]);
    restart_wdt();
  }
  while(1)
  {
    restart_wdt();
  }
}
//========================= Functions ==============================//
//=== init ===//  setup the initial settings
void init(void){
  output_low(PIN_C5);//turn off the TX_enable
  setup_timer_0(RTCC_INTERNAL);
  setup_wdt(WDT_ON);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  set_tris_a(0xFF);set_tris_b(0xFF);set_tris_c(0xFF);set_tris_d(0xFF);set_tris_e(0xFF);
  fprintf(DEBUG,"Firm=%C_%03u.c\n\r",FIRM_MAJOR,FIRM_MINOR);
  fprintf(DEBUG,"Hard=%2u.%02u\n\r",HARD_MAJOR,HARD_MINOR);
  enable_interrupts(GLOBAL);
  restart_wdt();
}
void force_change_flags(int16 startChan, int16 endChan, int1 value)
{
  int16 curChan,B_idx,b_idx;
  for (curChan=startChan;curChan<=endChan;curChan++)
  {
    restart_wdt();
    B_idx=curChan/8;//Byte index
    b_idx=curChan%8;//bit index
    if(value){
      bit_set  (flagByte[B_idx],b_idx);
      fprintf(DEBUG,"S %lu 0x%2X 0x%2X\n\r",curChan,B_idx,b_idx);
    }
    else{
      bit_clear(flagByte[B_idx],b_idx);
      fprintf(DEBUG,"C %lu 0x%2X 0x%2X\n\r",curChan,B_idx,b_idx);
    }
    //dmxChange.flagBit[i] = value;
  }
}


Last edited by treitmey on Tue Jan 22, 2008 3:13 pm; edited 3 times in total
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

PostPosted: Tue Jan 22, 2008 3:01 pm     Reply with quote

Sure. The union is part of my current workaround -- I've written a function that goes into the same array in byte format and sets an individual bit within a byte, starting with the same 16-bit index value that doesn't work in the previously posted code. This function works fine, so I have a working application, albeit more verbose than I'd like.

Declaring the bit array by itself, not inside a union, does not make any difference -- I can only access the first 256 index positions if the index is a variable.

But if the index is a literal rather than a variable, it works with any value, right up to the required max of 528 elements.

So, my question is: have I made a coding error, or have I found a compiler bug, or is it a known spec that the indices of a bit array can only be 8 bits wide?
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

PostPosted: Tue Jan 22, 2008 3:49 pm     Reply with quote

Thanks, but I already have a workaround function, and it's pretty much what you've written. I can get the job done. :)

My question is about using a bit array in the form
Code:
MyBits[index]

Where index is an int16 variable with a value greater than 255. It doesn't work for me. But it does work if index is a literal. Have I found a compiler bug, or is this normal?
Ttelmah
Guest







PostPosted: Wed Jan 23, 2008 5:28 am     Reply with quote

Bit arrays in CCS, are relatively 'new' (only a few versions ago, we'd have been saying "can't do this"). Now, historically, CCS, for a long while had a limit on arrays, only allowing int (int8) indexes. This has been removed on latter versions, so the question is "has this limit 'come back', when dealing with int1 arrays"?.
Looking at the assembler generated for an int1 array access, shows that if you access a single bit in such an array, using a constant index, it does handle values beyond 255, so:
Code:

....................    bitarray[0x10]=0;
01CA:  BCF    07.0
....................    bitarray[0x110]=0;
01CC:  BCF    27.0

However if you do the same, with an int16 variable (in this case, counting through 512 entries), you get:
Code:

....................    for (count=0;count<512;count++)
01A8:  CLRF   48
01AA:  CLRF   47
01AC:  MOVF   48,W
01AE:  SUBLW  01
01B0:  BNC   01CA
....................       bitarray[count]=1;
01B2:  MOVFF  47,49
01B6:  MOVLW  01
01B8:  MOVWF  4A
01BA:  CLRF   4C
01BC:  MOVLW  05
01BE:  MOVWF  4B
01C0:  BRA    0004
01C2:  INCF   47,F
01C4:  BTFSC  FD8.2
01C6:  INCF   48,F
01C8:  BRA    01AC

If you look carefully at the start of the section accessing the array, you will see that it takes the LSB of the 16bit value (stored in 47), and transfers it to a temporary variable, prior to calling the access routine (here at address 4), but it does not take the MSB at all for the access (only talks to this for the increment, and tests for the loop...).
So it appears as if the bit array code, at present is limited to 8bit, when variables are used.
I'd 'moan' slightly at CCS, since this should at the very least be documented, if not fixed....

Best Wishes
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

PostPosted: Wed Jan 23, 2008 7:04 am     Reply with quote

Thanks! That's the confirmation I was hoping to find. I have contacted CCS.
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

PostPosted: Thu Jan 24, 2008 1:05 pm     Reply with quote

CCS reports that they have fixed my problem and it will be in the next compiler release. :)

Jim
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group