RAK4630 Custom Firmware SPI Problem


This post is part of this topic; RAK4630 Custom Firmware

I am having a problem with SPI.
I have created my own software based on the libraries in here: https://github.com/beegee-tokyo/SX126x-Arduino But I could not succeed.

Here is my main function;

/**@brief Function for application main entry. */
int main (void)
    uint32_t err_code;
    // Initialize logs.
    NRF_LOG_INFO("LoRaWan Class A example started.");
    // Initialize clocks

    // Enable nRF52 DCDC

    // Initialize Scheduler and timer
    err_code = timers_init();
    if (err_code != NRF_SUCCESS)
        NRF_LOG_ERROR("timers_init failed - %d", err_code);
        return err_code;
    // Initialize LoRa chip.
    err_code = lora_hardware_init();
    if (err_code != NRF_SUCCESS)
        NRF_LOG_ERROR("lora_hardware_init failed - %d", err_code);
        return err_code;
    // Initialize LoRaWan
    err_code = lmh_init(&lora_callbacks);
    if (err_code != NRF_SUCCESS)
        NRF_LOG_ERROR("lmh_init failed - %d", err_code);
        return err_code;

    // Start Join procedure
    app_timer_start(lora_tx_timer_id, APP_TIMER_TICKS(LORAWAN_APP_TX_DUTYCYCLE), NULL);
    // Enter main loop.
    for (;;)
        if (NRF_LOG_PROCESS() == false)

Here is my lora_hardware_init function;

uint32_t lora_hardware_init (void)


	volatile uint16_t readSyncWord = 0;
	SX126xReadRegisters(REG_LR_SYNCWORD, (uint8_t *)&readSyncWord, 2);
    return NRF_SUCCESS;

Here is my spi-board.c file;

#include "spi-board.h"
#include "board.h"

volatile bool xferDone;

/** @brief SPI master driver event handler type. */
static void nrf_drv_spi_evt_handler(nrf_drv_spi_evt_t const * p_event, void *p_context)
	xferDone = true;

void SpiInit (Spi_t *obj, uint32_t mosi, uint32_t miso, uint32_t sclk, uint32_t nss)
    uint32_t err_code;
    nrf_drv_spi_config_t config = NRF_DRV_SPI_DEFAULT_CONFIG;
    const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);
    obj->Spi = spi;
    config.frequency	= NRF_DRV_SPI_FREQ_8M;
    config.miso_pin     = miso;
    config.mosi_pin     = mosi;
    config.sck_pin      = sclk;
    config.ss_pin       = nss;
    err_code = nrf_drv_spi_init (&(obj->Spi), &config, nrf_drv_spi_evt_handler, NULL);	
    APP_ERROR_CHECK (err_code);

void SpiDeInit (Spi_t *obj)
    nrf_drv_spi_uninit (&(obj->Spi));	

uint16_t SpiInOut (Spi_t *obj, uint16_t outData)
    uint32_t err_code;
    uint8_t inData ;

    if ((obj == NULL) || (&(obj->Spi) == NULL))
        APP_ERROR_CHECK_BOOL (false);
	xferDone = false;

    err_code = nrf_drv_spi_transfer (&(obj->Spi), (uint8_t*)&outData, 1, (uint8_t*)&inData, 1);

    return (uint16_t)inData;

Here is my problem. When I try to read REG_LR_SYNCWORD register, I get 0x00 and it does not seem to be correct. Do you have any idea what am I missing here?
Side note: I am using RAK4630 with my own PCB.
Side note 2: Here are my pin definitions;

#define PIN_LORA_DIO_1          NRF_GPIO_PIN_MAP(1, 15)      // LORA DIO_1
#define PIN_LORA_DIO_2          NRF_GPIO_PIN_MAP(1, 07)      // LORA DIO_2
#define PIN_LORA_BUSY           NRF_GPIO_PIN_MAP(1, 14)      // LORA BUSY
#define PIN_LORA_RESET          NRF_GPIO_PIN_MAP(1, 06)      // LORA RESET
#define PIN_LORA_ANTSW          NRF_GPIO_PIN_MAP(1, 05)      // LORA ANTSW

#define PIN_LORA_NSS            NRF_GPIO_PIN_MAP(1, 10)      // LORA SPI CS
#define PIN_LORA_MISO           NRF_GPIO_PIN_MAP(1, 13)      // LORA SPI MISO
#define PIN_LORA_MOSI           NRF_GPIO_PIN_MAP(1, 12)      // LORA SPI MOSI
#define PIN_LORA_SCLK           NRF_GPIO_PIN_MAP(1, 11)      // LORA SPI CLK

Do you have any idea? I could not be able to start the Lora module successfully without the Arduino library.
Side note 3: I did not try to run arduino library. I tried the RAK wireless Arduino library with their suggestions on the web.

I have an update on this. There was a definition on the board.h file like;define NRF_NUM_GPIO_PINS 32 And I changed it to; #define NRF_NUM_GPIO_PINS 49
But now I am getting HardFault_Handler and it is happening randomly. Not a specific and a constant function.

I cannot help much with Nordic SDK code, I never used it.
Your pin definitions are correct, but please do not setup DIO2. Even DIO2 is connected to the nRF52, it is used by the SX1262 to control the antenna switch. You should only set it as input, if you need it to debug the antenna switch function.

How is your power supply to the RAK4630? How are VBAT_SX, VBAT_IO_SX, VBAT_NRF and VDD_NRF connected?

On the WisBlock Core module the connections are
VBAT_SX ==> 3.3V from regulator
VBAT_IO_SX => 3.3V from regulator
VBAT_NRF ==> VBAT from battery
VDD_NRF ==> not connected (internal DC/DC of nRF52 is creating VDD_NRF from VBAT_NRF)

Thank you for your response!
I already setup DIO2 pin as Input. Am I missing something or is it just a suggestion?
Does the antenna pin block working the Sx1262 if there is something wrong with the pin setup?
Here is my power connections;

I connected them all together. Is it wrong? But with the same connection, I can successfully run the LoRaWAN example in the RAK Arduino library (RUI).

If it works with Arduino based firmware, your electrical setup is correct.

So I guess the problem is within your setup code for the SPI. But as I mentioned, I cannot help there, I never used Nordic SDK and have no idea how to setup SPI properly with it.

So, do you have any idea about clock configuration?
SPI is not that complex.

I fixed the problem after removing the spi event handler function.
Here is my new spi init function call: err_code = nrf_drv_spi_init (&(obj->Spi), &config, NULL, NULL);
New issue:
What is the correct way to create the network keys?


The DevEUI is printed on the RAK4630 label.

The AppKey can be generated in the LoRaWAN server.

The AppEUI can be generated in the LoRaWAN server. If you are using Chirpstack LNS, the AppEUI is not required.

What LNS are you using? We have tutorials for TTN in our Documentation Center

Thank you.
I am using TTN. What confuses me is that the keys MSB and LSBs.
Which order I should enter the values to TTN and the end device?

Enter on both TTN and the device in MSB.

I am using TTN. Here is my key values;

 / _____)             _              | |
( (____  _____ ____ _| |_ _____  ____| |__
 \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 _____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
    (C)2015 Semtech

Description: End device commissioning parameters

License: Revised BSD License, see LICENSE.TXT file include in the project

Maintainer: Miguel Luis and Gregory Cristian

 * When set to 1 the application uses the Over-the-Air activation procedure
 * When set to 0 the application uses the Personalization activation procedure
#define OVER_THE_AIR_ACTIVATION         1

/**@breif Indicates if the end-device is to be connected to a private or public network
#define LORAWAN_PUBLIC_NETWORK          true

 * When set to 1 DevEui is LORAWAN_DEVICE_EUI
 * When set to 0 DevEui is automatically generated by calling BoardGetUniqueId function
#define STATIC_DEVICE_EUI               0

/**@brief Mote device IEEE EUI (big endian)
 * @remark see STATIC_DEVICE_EUI comments
#define LORAWAN_DEVICE_EUI              {0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x05, 0x37, 0x61}

/**@brief Application IEEE EUI (big endian)
#define LORAWAN_APPLICATION_EUI         {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90}

/**@brief AES encryption/decryption cipher application key
#define LORAWAN_APPLICATION_KEY         {0xE4, 0x54, 0xB5, 0xD2, 0x4A, 0x6B, 0xFB, 0x8C, 0x4A, 0x17, 0x6D, 0x24, 0x31, 0x4E, 0x2E, 0x5C}

/**@brief Current network ID
#define LORAWAN_NETWORK_ID              (uint32_t)0

 * When set to 1 DevAdd is LORAWAN_DEVICE_ADDRESS
 * When set to 0 DevAdd is automatically generated using
 *         a pseudo random generator seeded with a value derived from
 *         BoardUniqueId value
#define STATIC_DEVICE_ADDRESS           1

/**@brief Device address on the network (big endian)
 * @remark In this application the value is automatically generated using
 *         a pseudo random generator seeded with a value derived from
 *         BoardUniqueId value if LORAWAN_DEVICE_ADDRESS is set to 0
#define LORAWAN_DEVICE_ADDRESS          (uint32_t)0x00000000

/**@brief AES encryption/decryption cipher network session key
#define LORAWAN_NWKSKEY                 {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}

/**@brief AES encryption/decryption cipher application session key
#define LORAWAN_APPSKEY                 {0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C}


And here is TTN keys;
rak4630 lorawan params

I never get join request. I only see uplink message;

Also I can not see any activity on the device page.

Do you have any idea?

I am comparing the one that I am using which it is exact copy of ISP4520 example and FreeRTOS example and @beegee 's library and as I see they are different. Is it about the version difference?

I see you selected EU868 on TTN.
If you do not see the join requests on the gateway, there can be a few reasons:

  • the device is not sending the join request (in my library that would be lmh_join()
  • the device is not set to EU868 (in my library that would be set in lmh_init()
  • the gateway is not setup to EU868
  • your device is not set to use OTAA but set to use ABP

If using ABP, there is no Join Request/Join Accept cycle.

  • both TTN and the device itself must be set to ABP
  • instead of DevEUI, AppEUI, AppKey you must setup DevAddress, AppsKey and NWSKey on both TTN and the device itself to the same.

The fact that you see the uplink messages and no join request points into the direction that you setup the device in ABP mode and not in OTAA mode.

Sorry for the late response.
I have a proof that device is running in OTAA mode. At least OTAA is enabled.

As long as you do not see the Join Requests in both the Gateway and in the TTN console there is a problem.

  • EUI’s/Keys not correct
  • wrong region / frequencies

Looking in your TTN gateway log (again), I see join requests, but neither the JoinEUI(==AppEUI) nor the DevEUI are matching with what you have setup in the TTN console.

Join request with DevEUI 2C C2 19 EA 70 C1 79 83 and AppEUI (JoinEUI) 10 00 00 00 00 00 00 09 :

are not matching with what you show from the TTN console :