I'm writing an initialization function on an ATTiny441 to set the data direction register (DDR) for Port A or B based on the physical pin number.
So far my implementation seems a bit clunky. Below is the initialization function in nrf.c
that I'll call in main.c
:
/* nrf.c */
#import <avr/io.h>
#import "t441.h"
bool ce_port_a;
uint8_t ce_bit;
void nrf_init(uint8_t ce_pin,
uint8_t csn_pin)
{
/* Map CE pin */
t441_map_pins(ce_pin, &ce_bit, &ce_port_a);
/* Set CE to output */
if(ce_port_a) DDRA |= BIT(ce_bit);
else DDRB |= BIT(ce_bit);
/* Clear CE */
_nrf_toggle_ce(0);
/* ... */
}
In the same nrf.c
, here's the function used to toggle the CE pin:
/* nrf.c */
void _nrf_toggle_ce(uint8_t direction)
{
/* Set CE */
if(direction) ce_port_a ? SET_BIT(PORTA, ce_bit) : SET_BIT(PORTB, ce_bit);
/* Clear CE */
else ce_port_a ? CLEAR_BIT(PORTA, ce_bit) : CLEAR_BIT(PORTB, ce_bit);
}
(Note the SET_BIT() and CLEAR_BIT() functions are defined elsewhere, but I assume that they're descriptive enough.)
And, finally, here's the function in t441.c
that maps the physical pin number to a Port and bit number:
/* t441.c */
uint8_t t441_port_b_map[4] = {0, 1, 3, 2};
void t441_map_pins(uint8_t pin_num, uint8_t *port_pin_num, bool *port_a)
{
if(pin_num < 6)
{
/* Pin is on Port B */
*port_a = false;
*port_pin_num = t441_port_b_map[pin_num - 2];
}
else
{
/* Pin is on Port A */
*port_a = true;
*port_pin_num = 13 - pin_num;
}
}
Question: Is there a simpler or more elegant way to approach this? I'm somewhat concerned with program memory usage but mainly with code re-usability — e.g. having to significantly change things if using a microcontroller with more than two IO ports.
(I'll move this to Stack Overflow if appropriate.)
Best Answer
I'm probably not the most qualified to answer, but I'll compile what folks have said thus far.
From Chris Stratton:
From Harry Svensson:
And from Lundin:
Seems like the best way to approach it is with preprocessor commands, e.g.
#ifdef
,#define
, and so on. Since I'm only using a single IC there's no need to waste memory on code portability.