uint8_t read_bitfield(const uint8_t register, const uint8_t lsb, const uint8_t len)
{
// const uint8_t mask = 0b0000_1100;
uint8_t mask = 0x0C;
// leemos el contenido del registro del IC
uint8_t temp_reg = read_register(register);
// 'multiplicamos' el contenido actual del registro con la mascara
// los bits que no nos interesan (todos los 0's en *mask*) se volveran 0, solo manteniendo
// intactos los bits que valen 1 en *mask*
temp_reg = temp_reg & mask;
// recorremos temp_reg *len* posiciones a la derecha
// porque solo nos interesa el valor del 'campo'
return temp_reg >> len;
}
uint8_t write_bitfield(const uint8_t register, const uint8_t val, const uint8_t lsb, const uint8_t len)
{
// const uint8_t mask = 0b0000_1100;
uint8_t mask = 0x0C;
// leemos el contenido del registro del IC
uint8_t temp_reg = read_register(register);
// multiplicando temp_reg con el inverso de mask
// se mantendran intactos los bits que no queremos modificar (1's en *mask* invertido) y
// ponemos se pondran en 0 el campo de bits que pretendemos escribir (0's en *mask* invertido)
temp_reg = temp_reg & (~(mask));
// recorremos a la izquierda el valor que queremos escribir *len* posiciones y lo escribimos en temp_reg
temp_reg = temp_reg | (val << len);
// escribimos el nuevo temp_reg al registro del IC
write_register(reg, temp_reg);
}
¿alguna forma con la cual pueda calcular la variable *mask*?Una posible forma:
¿algun consejo con respecto al pseudo código?en la función write_bitfield deberías asegurarte de que el argumento val contiene un valor que en efecto sea representable solamente por len bits, de otra forma corres riesgo de que alteres otros bits que no se espera sean afectados.
¿alguna forma con la cual pueda calcular la variable *mask*?Te doy otra opcion ademas de la que te dio Geo.
¿algun consejo con respecto al pseudo código?Como te decia al comienzo, te comento el porque decia antes eso.
Disculpa Carl pero no entiendo que estas intentando hacer. Me refiero a hacer todo eso. Por ahora voy a seguir tu codigo, luego te digo lo que pienso que para mi seria lo mas simple.Hola, y si, me re complique la vida, haciendo lo que propones (leer el registro y hacer & con algun valor ya establecido) es mucho más fácil, así no tengo que añadir más funciones a la librería, sólo algunos define.Citar¿alguna forma con la cual pueda calcular la variable *mask*?Te doy otra opcion ademas de la que te dio Geo.Código: C
uint8_t calc_mask[8] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF}; if(len > 7) len = 7; // Proteccion calc_mask[len];Citar¿algun consejo con respecto al pseudo código?Como te decia al comienzo, te comento el porque decia antes eso.
¿Por que lo digo?
Supongamos por un momento que tengamos un IC con registros de 8bits y quisieramos obtener el estado de 1 o 2 de los bits. Primero lo que haria es una funcion que simplemente lea el registro completo sin ninguna mascara. Luego crearia un par de #define con los bits de interes
Quiero saber de algun bit?, supongamos que el bit se llama DONE, registro STATUS, integrado ADS9999 (inventado)
Funcion de lectura:Código: C
uint8_t ADS9999_Read(uint8_t RegisterAddress) { // Simplemente leer el registro completo y nada mas }
En el .h de la libreria del ADSCódigo: CPara saber si ese bit esta activo:
#define ADS9999_STATUS_BASE 0x84 #define ADS9999_STATUS_DONE 0x08Código: C
if ( ADS9999_Read(ADS9999_STATUS_BASE) & ADS9999_STATUS_DONE ) { // aca dentro detectado }
En tu codigo,
Hola,¿alguna forma con la cual pueda calcular la variable *mask*?Una posible forma:Código: C
uint8_t calc_mask(const uint8_t lsb, const uint8_t len) { uint8_t mask = 0; for (int i = lsb; i < lsb + len; i++) { mask |= (1 << i); } return mask; }¿algun consejo con respecto al pseudo código?en la función write_bitfield deberías asegurarte de que el argumento val contiene un valor que en efecto sea representable solamente por len bits, de otra forma corres riesgo de que alteres otros bits que no se espera sean afectados.