nRF24L01+ set register

salve,
sto cercando di capire come modificare il registro (è la prima volta che lo faccio) di questo modulo per impostare alcune funzioni non direttamente supportate dalla libreria.
la libreria Mirf offre questa classe:

void Nrf24l::configRegister(uint8_t reg, uint8_t value)
// Clocks only one byte into the given MiRF register
{
writeRegister(reg, &value, 1);
}

a pagina 58 del datasheet ci sono i riferimenti al registro RF_SETUP che vorrei modificare.
nei commenti della libreria ho trovato questo esempio che imposta la massima potenza di trasmissione
Mirf.configRegister( RF_SETUP, ( 1<<2 | 1<<1 ) );
ciò significa (correggetemi se sbaglio) che imposta il secondo e il primo bit a 1?

quindi, se ho capito bene, per impostare ad esempio CONT_WAVE (bit 7) dovrei scrivere
Mirf.configRegister( RF_SETUP, ( 1<<7 );

c’ho preso? :slight_smile:

ricdata:
Mirf.configRegister( RF_SETUP, ( 1<<2 | 1<<1 ) );
ciò significa (correggetemi se sbaglio) che imposta il secondo e il primo bit a 1?

sì, se inizi a contare da 0.

( 1<<2 | 1<<1 ) == 00000110

ricdata:
quindi, se ho capito bene, per impostare ad esempio CONT_WAVE (bit 7) dovrei scrivere
Mirf.configRegister( RF_SETUP, ( 1<<7 );

sì, se inizi a contare da 0.

 ( 1<<7  ) == 10000000

edit: per chiarirci:

( 1<<0 ) == 00000001

Nelle operazioni di shift si indica la posizione del bit ma, come ha precisato lesto, iniziando a contare da 0.
Ecco le posizioni dei bit di un byte:
76543210
1<<0 corrisponde a dire: metti “1” nel registro e poi spostalo di 0 posizioni a SX, il che equivale a dire: metti ad 1 il bit in posizione 0.
1<<1 corrisponde a dire: metti “1” nel registro e poi spostalo di 1 posizioni a SX, il che equivale a dire: metti ad 1 il bit in posizione 1.
ecc…

grazie ragazzi.
avete più volte specificato "se inizi a contare da zero", perchè si può iniziare anche da un'altra posizione? essendo uno shift register (l'ho capito solo ora) il bit di ingresso non è sempre il primo (LSB)?

un’altra domanda:
se ad esempio mi trovo il registro impostato così
0011001
e voglio mettere il bit 7 a 1 scrivo
1<<7
faccio “shiftare” un 1 dal bit 0 al 7, ma a questo punto i bit 6-5-4-3-2-1-0 si cancellano?

Tu hai scritto:

Mirf.configRegister( RF_SETUP, ( 1<<2 | 1<<1 ) );
ciò significa (correggetemi se sbaglio) che imposta il secondo e il primo bit a 1?

E’ sbagliato. Il bit 0 è il bit in prima posizione. Quindi nell’esempio si parla del 3° e del 2° bit, perché:
posizione 0 = 1° bit
posizione 1 = 2° bit
posizione 2 = 3° bit

posizione 7 = 8° bit.

ricdata:
perchè si può iniziare anche da un’altra posizione?

In realtà si conta sempre da 0 ma si può casomai partire a memorizzare i dati da sinistra oppure da destra . Nel primo caso si parla di architetture Big Endian (esempio i Motorola 68000) mentre nel secondo di architetture Little Endian (esempio: Intel x86).

ricdata:
un’altra domanda:
se ad esempio mi trovo il registro impostato così
0011001
e voglio mettere il bit 7 a 1 scrivo
1<<7
faccio “shiftare” un 1 dal bit 0 al 7, ma a questo punto i bit 6-5-4-3-2-1-0 si cancellano?

In questo particolare caso sì. Perché tutti i bit vengono spostati.
Ma nel caso della funzione messa nel 1° post molto probabilmente no perché sicuramente useranno operazioni di AND o OR sui bit per cambiare i singoli bit.
In questo mio articolo parlo delle porte logiche dei micro e di come settare i vari bit, ti è utile per capire come cambiare lo stato di uno (o più) bit di un registro senza modificare gli altri:
http://www.leonardomiliani.com/2013/manipoliamo-direttamente-le-porte-logiche-di-una-mcu/

perchè si può iniziare anche da un’altra posizione?

è una convenzione.

se parti da 0 i bit sono
7 6 5 4 3 2 1 0

se parti da 1 sono
8 7 6 5 4 3 2 1
(il modo in cui ragionavi tu, credo)

0011001
e voglio mettere il bit 7 a 1 scrivo
1<<7
faccio “shiftare” un 1 dal bit 0 al 7, ma a questo punto i bit 6-5-4-3-2-1-0 si cancellano?

no, vengono scifatati, ovvero viene inserito uno 0 a destra. il bit in posizione più a siniostra invece viene perso, ovvimanente non è detto che sia l’ottavi bit: se lavoro con gli int è il 16esimo, con i logng il 32esimo etc…
passo passo:

00011001
<<1 
00110010
<<1
01100100
<<1
11001000
<<1
10010000
<<1
00100000
<<1
01000000
<<1
10000000

se vuoi cambuare un solo bit, lasciando gli altri inalterati, devi usare la logica bitwise. cerca su google

leo72:
In realtà si conta sempre da 0 ma si può casomai partire a memorizzare i dati da sinistra oppure da destra . Nel primo caso si parla di architetture Big Endian (esempio i Motorola 68000) mentre nel secondo di architetture Little Endian (esempio: Intel x86).

attento! confondi bit e byte
ti stai riferendo alla Bit endianness, o più correttamente alla Bit numbering

edit: ma insomma, mi passi ai pic ma ti fai ancora beccare in castangna :slight_smile:

ok, siete stati molto chiari.

la funzione usata è questa:

void Nrf24l::configRegister(uint8_t reg, uint8_t value)
// Clocks only one byte into the given MiRF register
{
csnLow();
spi->transfer(W_REGISTER | (REGISTER_MASK & reg));
spi->transfer(value);
csnHi();
}
nel commento c’è un errore giusto? si tratta di un bit non un byte

mentre questa imposta un intero byte
void Nrf24l::writeRegister(uint8_t reg, uint8_t * value, uint8_t len)
// Writes an array of bytes into inte the MiRF registers.
{
csnLow();
spi->transfer(W_REGISTER | (REGISTER_MASK & reg));
transmitSync(value,len);
csnHi();
}
anche qui il commento non è esatto, sarebbe corretto dire:
Writes an array of bit into inte the MiRF registers

scusate se ne approfitto.... aggiungo un ultima domanda (lo giuro)
la scrittura di uno shift register è permanente oppure dopo un reset dell mcu vengono rispristinati i valori di default?
immagino di no, ma chiedo conferma.

grazie ancora

no, la prima scrive un BYTE, ovvero 8 bit alla volta.
la seconda scrive un array di BYTE, che poi a loro volta siano bit poco ci importa, il "mattoncino" minimo che viene scritto è il byte.

in pratica tu devi:

  1. leggere il registro in una variabile (tipicamente un byte, ma non è dempre detto)
  2. cambiare solo i bit che ti interessanto nella variabile con la logica bitwise
  3. scrivere la variabile nel registro

In tal modo sovrascriverai anche i valori che non vuoi cambiare, e non puoi farne a meno, ma almeno li riscrivi con i vecchi valori, quindi di cfatto non cabi niente.

ricdata:
scusate se ne approfitto.... aggiungo un ultima domanda (lo giuro)
la scrittura di uno shift register è permanente oppure dopo un reset dell mcu vengono rispristinati i valori di default?
immagino di no, ma chiedo conferma.

grazie ancora

Uno shift register è un componente hardware :stuck_out_tongue:
Qui si parla dello shift di un registro :wink:
I registri di un microcontrollore sono mappati in RAM. Se resetti il chip tutto torna ai valori di default.

lesto:
in pratica tu devi:

  1. leggere il registro in una variabile (tipicamente un byte, ma non è dempre detto)
  2. cambiare solo i bit che ti interessanto nella variabile con la logica bitwise
  3. scrivere la variabile nel registro

in che modo posso leggere un registro?

Un registro altro non è che una cella mappata in RAM. Il compilatore ci accede con una macro, esempio TCNT2. Dipende da che registro devi leggere/scrivere.
I registri sono quelli documentati nel datasheet del microcontrollore, ed il compilatore li rimappa con lo stesso nome.

PS:
hai letto il link che ti ho passato? Lì c'erano spiegate un bel pò di cose, mi sa che non lo hai fatto vero? :wink:

ricdata:

lesto:
in pratica tu devi:

  1. leggere il registro in una variabile (tipicamente un byte, ma non è dempre detto)
  2. cambiare solo i bit che ti interessanto nella variabile con la logica bitwise
  3. scrivere la variabile nel registro

in che modo posso leggere un registro?

esattamente come fa la libreria a leggere i valori di ritorno.. sei riuscito ad estrrarre le funzioni che effettuano le scritture, cerca bene e troverai quelle di lettura :slight_smile:

@leo: occhio che parliamo di registri di un chip esterno, non quelli arduino

Sono state un pò mescolate le cose, ad un certo punto, e mi sono perso.

lesto:
esattamente come fa la libreria a leggere i valori di ritorno.. sei riuscito ad estrrarre le funzioni che effettuano le scritture, cerca bene e troverai quelle di lettura :slight_smile:

giusto! mi sono lasciato prendere dalla fretta di postare senza riflettere troppo, scusate.
appena posso provo.

leo72:
Sono state un pò mescolate le cose, ad un certo punto, e mi sono perso.

tranquillo, ti vogliamo bene lo stesso :slight_smile: