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
-
@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.
-
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
-
@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.h
now looks like this, but I am not sure how to change theinitSPI()
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.
-
@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.
-
@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