MBSBootloader with different CSN/CE Pin problem



  • Hello all,

    I am trying to make a new bootloader where the CSN and CE pins are connected to pin 7 and 8. (CSN = 7 and CE = 8 ).

    This is what I changed in the bootloader:

    // SPI communication
    
    #define SPI_DDR		DDRB
    #define SPI_PORT	PORTB
    #define SPI_PORT2   PORTD
    #define SPI_PIN		PINB
    #define	SPI_SCLK	5		// Arduino Pin 13 <-> Bit 5 of port B
    #define	SPI_MISO	4		// Arduino Pin 12 <-> Bit 4 of port B
    #define	SPI_MOSI	3		// Arduino Pin 11 <-> Bit 3 of port B
    #define	SPI_CSN		7		// Arduino Pin 7 <-> Bit 7 of port D
    //#define	SPI_CSN		2		// Arduino Pin 10 <-> Bit 2 of port B
    #define	SPI_CE		0		// Arduino Pin  8 <-> Bit 0 of port B
    //#define	SPI_CE		1		// Arduino Pin  9 <-> Bit 1 of port B
    #define CE_PULSE_LENGTH	20	// IMPORTANT: minimum CE pulse width 10us, see nRF24L01 specs. Set 20us to be on the safe side
    
    #define csnlow() DDRD &= ~_BV(SPI_CSN)
    #define csnhigh() DDRD |= _BV(SPI_CSN)
    
    #define celow() SPI_PORT &= ~_BV(SPI_CE)
    #define cehigh() SPI_PORT |= _BV(SPI_CE)
    
    static void SPIinit() {
    	// set pin mode: MOSI,SCLK,CE = OUTPUT, MISO = INPUT
    	SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(SPI_CE) | ~_BV(SPI_MISO);
        // Set CSN = output
    	DDRD = _BV(SPI_CSN);
    }
    

    I uploaded the firmware to an Arduino and want to connect it to another Arduino which is programmed with the Serial Gateway sketch.
    For discovery of nodes I use the MYSController software on windows, this is working correctly as I can discover my temperature node (which is programmed via arduino with the normal arduino bootloader).

    But I can't get it to work, am I missing something?
    I checked the settings in MyConfig (channel, power etc) but these are the same on the serial gateway sketch and the bootloader.

    Compiler output for bootloader:

    "C:/Program Files (x86)/Arduino/hardware/tools/avr/bin/avr-gcc" -x c -mno-interrupts -funsigned-char -funsigned-bitfields -DF_CPU=16000000L -Os -fno-inline-small-functions -fno-split-wide-types -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -Wall -mmcu=atmega328p -c -std=gnu99 -MD -MP -MF "MYSBootloader.d" -MT"MYSBootloader.d" -MT"MYSBootloader.o"  -I../libraries/MySensors MYSB
    ootloader.c -o MYSBootloader.o
    In file included from MYSBootloader.c:44:0:
    MYSBootloader.h:28:2: warning: no semicolon at end of struct or union [enabled by default]
      };
      ^
    In file included from MYSBootloaderRF24.h:4:0,
                     from MYSBootloader.h:13,
                     from MYSBootloader.c:44:
    MYSBootloaderHW.h:96:13: warning: 'uart_init' defined but not used [-Wunused-function]
     static void uart_init() {
                 ^
    MYSBootloaderHW.h:126:13: warning: 'put_int' defined but not used [-Wunused-function]
     static void put_int(uint8_t i) {
                 ^
    "C:/Program Files (x86)/Arduino/hardware/tools/avr/bin/avr-gcc" -nostartfiles -Wl,-s -Wl,-static -Wl,-Map=".map" -Wl,--start-group  -Wl,--end-group -Wl,--gc-sections -mrelax -Wl,-section-start=.text=0x7800 -mmcu=atmega328p   -o MYSBootloader.elf MYSBootloader.o -lm
    "C:/Program Files (x86)/Arduino/hardware/tools/avr/bin/avr-objcopy" -O ihex -R .eeprom MYSBootloader.elf MYSBootloader.hex
    "C:/Program Files (x86)/Arduino/hardware/tools/avr/bin/avr-size" MYSBootloader.elf
       text    data     bss     dec     hex filename
       2004       2     214    2220     8ac MYSBootloader.elf
    

    Thanks for reading!

    • Ruud

  • Admin

    @Ruud-Harmsen you use the data direction register (DDRD) instead of PORTD to control CSN.



  • Thanks @tekka, that worked!

    I attached the bootloader for other interested people.

    Settings:
    CSN pin: 7
    CE pin: 8

    #define RF24_CHANNEL	   90             //RF channel for the sensor net, 0-127
    #define RF24_DATARATE 	   RF24_250KBPS   //RF24_250KBPS for 250kbs, RF24_1MBPS for 1Mbps, or RF24_2MBPS for 2Mbps
    #define RF24_PA_LEVEL 	   RF24_PA_MAX    //Sensor PA Level == RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBM, and RF24_PA_MAX=0dBm
    #define RF24_PA_LEVEL_GW   RF24_PA_LOW  //Gateway PA Level, defaults to Sensor net PA Level.  Tune here if using an amplified nRF2401+ in your gateway.
    #define BASE_RADIO_ID 	   ((uint64_t)0xA8A8E1FC00LL) // This is also act as base value for sensor nodeId addresses. Change this (or channel) if you have more than one sensor network.
    

    MYSBootloader.hex



  • For some reason, @Ruud-Harmsen's bootloader didn't work for me.

    My copy's attached. Same pins and rf24 config; but also added five flashes to an LED connected to pin D9, so you can tell when it's in a reboot loop.

    Source here: https://github.com/peterdey/MySensors-Arduino/tree/master/MYSBootloader

    MYSBootloader.hex



  • @tekka I also did some changes to assign the SPI pins CSN to pin 9 and CE to pin 8.

    So the code in the HW.hnow looks like this, but I am not sure how to change the initSPI() method:

    #elif defined(SPI_PINS_CSN9_CE8)
    	#define CSN_PORT	PORTB	// port for CSN
    	#define CSN_DDR		DDRB	// DDR for CSN
    	#define	CSN_PIN		PB1		// Arduino Pin 9 <-> Bit 1 of port B
    
    	#define CE_PORT		PORTB	// port for CE
    	#define CE_DDR		DDRB	// DDR for CE
    	#define	CE_PIN		PB0		// Arduino Pin  8 <-> Bit 0 of port B
    #endif
    
    
    static void initSPI(void) {
    	// Initialize the SPI pins: SCK, MOSI, CE, CSN as outputs, MISO as input
    	#if defined(SPI_PINS_CE9_CSN10)
    		// CSN_PIN (=PB2) is SS pin and set as output
    		SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(CSN_PIN);
    	#elif defined(SPI_PINS_CSN7_CE8)
    		// PB2 is SS pin has to be defined as OUTPUT, else SPI goes to slave mode
    		SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(PB2);	
    		CSN_DDR = _BV(CSN_PIN);
    	#elif defined(SPI_PINS_CSN9_CE8)
    		// set pin mode: MOSI,SCLK,CE,CSN = OUTPUT, MISO = INPUT
    		SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(CSN_PIN) | ~_BV(SPI_MISO);
    		// set CSN = output
    		CSN_DDR = _BV(CSN_PIN);
    	#endif
    

    Is there any further code I have to change?

    Thanks in advance for any hint, I am not used to code on that bit level and AVR macros.


  • Admin

    @dirkc said in MBSBootloader with different CSN/CE Pin problem:
    I guess you should also set PB2 as output to enable SPI master mode (regardless of your csn assignment)



  • Thanks, @tekka, but unfortunately I am still using the wrong code. I tried every combination, but as I am not sure what am doing here, I doubt to make progress.

    set MOSI,SCLK,CE,CSN to OUTPUT -> SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(CSN_PIN)
    set PB2 to OUTPUT -> | _BV(PB2)
    set MISO to INPUT -> | ~_BV(SPI_MISO)
    and set CSN to output -> CSN_DDR = _BV(CSN_PIN);

    The controller still doesn't recognize the node, so I cannot use OTA. But when I flash the sketch (with the CE and CSN pin defined to 8 and 9) with a programmer to an atmega328p with a standard bootloader it works, so my PCB seems ok.

    #elif defined(SPI_PINS_CSN9_CE8)
    	// set pin mode: MOSI,SCLK,CE,CSN = OUTPUT, MISO = INPUT
    	// PB2 is SS pin has to be defined as OUTPUT, else SPI goes to slave mode
    	SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN)  | _BV(CSN_PIN) | _BV(PB2) | ~_BV(SPI_MISO);
    	// set CSN = output
    	CSN_DDR = _BV(CSN_PIN);
    #endif
    

    Looking to other bootloaders was no success, e.g. optiboot.

    Thanks in advance for any hint or better some sample code.


  • Admin

    @dirkc Unfortunately I cannot test the setup right now, but this should work:

    ...
    ...
    #elif defined(SPI_PINS_CSN9_CE8)
    	#define CSN_PORT	PORTB	// port for CSN
    	#define CSN_DDR		DDRB	// DDR for CSN
    	#define	CSN_PIN		PB1		// Arduino Pin 9 <-> Bit 1 of port B
    
    	#define CE_PORT		PORTB	// port for CE
    	#define CE_DDR		DDRB	// DDR for CE
    	#define	CE_PIN		PB0		// Arduino Pin  8 <-> Bit 0 of port B
    #endif
    

    and

    static void initSPI(void) {
    	...
            ...
    	#elif defined(SPI_PINS_CSN9_CE8)
    		// set pin mode: MOSI,SCLK,CE,CSN = OUTPUT, MISO = INPUT (=> all on same port)
    		SPI_DDR = _BV(SPI_MOSI) | _BV(SPI_SCLK) | _BV(CE_PIN) | _BV(CSN_PIN) | ~_BV(SPI_MISO);
    	#endif
    

 

Suggested Topics

269
Online

7.6k
Users

8.5k
Topics

91.2k
Posts