how to combine those two routines into one (function overloading)

so I have those two routines in a library I made that essentially do the same thing except that one takes a uin16_t array and the other a uint32_t array (function overloading)

I could used if-else for the differences within the routine but how to deal with the diffenrent array types I am stumped.

if it were just a variable, I could cast the uin16_t to a uin32_t then pass to the uin32_t routine but since its an array… :confused: :confused: :confused:

any constructive suggestions appreciated.

//uint16_t function

uint8_t MCP2515::init_filter(uint16_t *Std_CAN_id_Arr, uint8_t std_arr_size, uint8_t reg_select)
{
uint16_t std;
uint8_t filter_regs[8] = {RXM0SIDH, RXF0SIDH, RXF1SIDH, RXM1SIDH, RXF2SIDH, RXF3SIDH, RXF4SIDH, RXF5SIDH};
uint8_t data[4] = {0xFF,0xFF,0xFF,0xFF};
uint8_t u_bound, rxbnctrl, i=0, j=0;

	// config mode
    write_register(CANCTRL, 0x80);
	
    if (read_register(CANCTRL) != 0x80) return 0;
	else if(std_arr_size>6) return 0;
	
	if(reg_select==0){
		//init RX mask registers. 11-bit mask: 0x7FF<----No masking applied to filter CAN Ids	
		memset(&data[2],0x00,2);
		write_register(filter_regs[0], data, 4);
		write_register(filter_regs[3], data, 4);
		u_bound = 8;
	}
	else if(reg_select==1){
		//init RXBUF1 mask for extended CAN IDs (No masking applied)
		write_register(filter_regs[3], data, 4);
		memset(&data[2],0x00,2);
		//init RXBUF0 mask for std CAN IDs (No masking applied)
		write_register(filter_regs[0], data, 4);
		u_bound = 3;
	} 
	else{
		write_register(filter_regs[0], data, 4);
		memset(&data[2],0x00,2);
		write_register(filter_regs[3], data, 4);
		u_bound = 8;		
	}
		
	for(i=reg_select;i<u_bound;++i){
		if(j<std_arr_size){
			uint8_t data[4] = {(*(Std_CAN_id_Arr+j) >> 3),(*(Std_CAN_id_Arr+j)<< 5),0,0};
			write_register(filter_regs[i], data, 4);
			++j;
		}
		else{
			uint8_t data[4] = {(*Std_CAN_id_Arr >> 3),(*Std_CAN_id_Arr << 5),0,0};
			write_register(filter_regs[i], data, 4);
		}		
	}
	
	// turn on filters => Receive all valid messages using either standard or extended identifiers that meet filter criteria
	rxbnctrl = ((~((1<<RXM1)|(1<<RXM0))) & read_register(RXB0CTRL))|(1<<BUKT);
	
	write_register(RXB0CTRL,rxbnctrl);
	
	rxbnctrl = (~((1<<RXM1)|(1<<RXM0))) & read_register(RXB1CTRL);
	
	write_register(RXB1CTRL,rxbnctrl);
	
	// normal mode
    write_register(CANCTRL, 0);
	
	return 1;
}

//uint32_t function

uint8_t MCP2515::init_filter(uint32_t *Ex_CAN_id_Arr, uint8_t ex_arr_size, uint8_t reg_select)
{
union { 
	uint32_t ex;
	struct{
		uint16_t std;
		uint16_t stdh;
	};
} id;

uint8_t filter_regs[8] = {RXM0SIDH, RXF0SIDH, RXF1SIDH, RXM1SIDH, RXF2SIDH, RXF3SIDH, RXF4SIDH, RXF5SIDH};
uint8_t data[4] = {0xFF,0xFF,0xFF,0xFF};
uint8_t u_bound, rxbnctrl, i=0, k=0;

	// config mode
    write_register(CANCTRL, 0x80);
	
    if (read_register(CANCTRL) != 0x80) return 0;
	else if(ex_arr_size>6) return 0;
	
	if(reg_select==0){
		//init RX mask registers. 29-bit mask: 0x1FFFFFFF <----No masking applied to filter CAN Ids	
		write_register(filter_regs[0], data, 4);
		write_register(filter_regs[3], data, 4);
		u_bound = 8;
	}
	else if(reg_select==1){
		write_register(filter_regs[0], data, 4);
		memset(&data[2],0x00,2);
		write_register(filter_regs[3], data, 4);
		u_bound = 3;
	} 
	else{
		write_register(filter_regs[3], data, 4);
		memset(&data[2],0x00,2);
		write_register(filter_regs[0], data, 4);
		u_bound = 8;		
	}
	
	for(i=reg_select;i<u_bound;++i){
		if(k<ex_arr_size){
			id.ex = *(Ex_CAN_id_Arr+k);
			uint8_t data[4] = {(id.stdh >> 5),(((id.stdh << 3)&0xE0)|(id.stdh&0x03)|0x08),(id.std >> 8),id.std};
			write_register(filter_regs[i], data, 4);			
			++k;
		}
		else{
			id.ex = *Ex_CAN_id_Arr;
			uint8_t data[4] = {(id.stdh >> 5),(((id.stdh << 3)&0xE0)|(id.stdh&0x03)|0x08),(id.std >> 8),id.std};
			write_register(filter_regs[i], data, 4);			
		}		
	}

	// turn on filters => Receive all valid messages using either standard or extended identifiers that meet filter criteria
	rxbnctrl = ((~((1<<RXM1)|(1<<RXM0))) & read_register(RXB0CTRL))|(1<<BUKT);
	
	write_register(RXB0CTRL,rxbnctrl);
	
	rxbnctrl = (~((1<<RXM1)|(1<<RXM0))) & read_register(RXB1CTRL);
	
	write_register(RXB1CTRL,rxbnctrl);
	
	// normal mode
    write_register(CANCTRL, 0);
	
	return 1;
}

I am certainly no expert on C/C++ programming but a technique I have seen in some libraries is to have the principal function defined as normal (crude example)

void myFunction(long speed, int duration, byte color) {

and then have an overloaded version

void myFunction(char * speed, int duration) {

and then the code in the second version manipulates the values, and maybe adds some default values, before calling the principal version with parameters that match it.

...R