Dear community,
I need to operate a BM833A as I2C slave and to do so, I performed the following steps:
I modfied my sdk_config.h and set TWIS_ENABLED and NRFX_TWIS_ENABLED identically following hint at:
devzone.nordicsemi.com/.../merge-twis-i2c-slave-example-in-ble_template-project
(Either completely remove the legacy (non NRFX_...) for TWI(S) or set them equal to the NRFX_TWIS_... definitions.)
// <e> NRFX_TWIS_ENABLED - nrfx_twis - TWIS peripheral driver
//==========================================================
#ifndef NRFX_TWIS_ENABLED
#define NRFX_TWIS_ENABLED 1
//RH: changed from 0 to 1
#endif
// <q> NRFX_TWIS0_ENABLED - Enable TWIS0 instance
#ifndef NRFX_TWIS0_ENABLED
#define NRFX_TWIS0_ENABLED 1
//RH: changed from 0 to 1
#endif
// <q> NRFX_TWIS1_ENABLED - Enable TWIS1 instance
#ifndef NRFX_TWIS1_ENABLED
#define NRFX_TWIS1_ENABLED 0
#endif
// <q> NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized only once
// <i> Optimization flag. Registers used by TWIS are shared by other peripherals. Normally, during initialization driver tries to clear all registers to known state before doing the initialization itself. This gives initialization safe procedure, no matter when it would be called. If you activate TWIS only once and do never uninitialize it - set this flag to 1 what gives more optimal code.
#ifndef NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY
#define NRFX_TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0
#endif
// <q> NRFX_TWIS_NO_SYNC_MODE - Remove support for synchronous mode
// <i> Synchronous mode would be used in specific situations. And it uses some additional code and data memory to safely process state machine by polling it in status functions. If this functionality is not required it may be disabled to free some resources.
#ifndef NRFX_TWIS_NO_SYNC_MODE
#define NRFX_TWIS_NO_SYNC_MODE 0
#endif
// <o> NRFX_TWIS_DEFAULT_CONFIG_ADDR0 - Address0
#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR0
#define NRFX_TWIS_DEFAULT_CONFIG_ADDR0 0x01
//RH: changed from 0 to 0x01
#endif
// <o> NRFX_TWIS_DEFAULT_CONFIG_ADDR1 - Address1
#ifndef NRFX_TWIS_DEFAULT_CONFIG_ADDR1
#define NRFX_TWIS_DEFAULT_CONFIG_ADDR1 0
#endif
// <o> NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL - SCL pin pull configuration
// <0=> Disabled
// <1=> Pull down
// <3=> Pull up
#ifndef NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL
#define NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL 3
//RH: enable pullup, see i2cslave from SBRLE
#endif
// <o> NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL - SDA pin pull configuration
// <0=> Disabled
// <1=> Pull down
// <3=> Pull up
#ifndef NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL
#define NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL 3
//RH: enable pullup, see i2cslave from SBRLE
#endif
// <o> NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
// <0=> 0 (highest)
// <1=> 1
// <2=> 2
// <3=> 3
// <4=> 4
// <5=> 5
// <6=> 6
// <7=> 7
#ifndef NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY
#define NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 6
#endif
I added to the segger-embedded-studio (SES) project file:
<folder Name="nRF_Drivers">
...
<file file_name="../../../../../../modules/nrfx/drivers/src/nrfx_twis.c" />
<folder>
Then I added code to main.c following:
I created a timer that executes continuously every 0.5s (function of that could be veryfied by LED blink).
Then I added I2C call to nrf_drv_twis_tx_prepare, hoping to get a transmission.
main.c modifications:
#include "nrf_drv_twis.h"
APP_TIMER_DEF(m_bsp_tmr);
//twi
/* TWI instance ID. */
#if TWIS0_ENABLED
#define TWIS_INSTANCE_ID 0
#endif
/* TWI instance. */
static const nrf_drv_twis_t m_twi = NRF_DRV_TWIS_INSTANCE(TWIS_INSTANCE_ID);
/**
* @brief TWI initialization.
*/
void twi_init (void)
{
ret_code_t err_code;
const nrf_drv_twis_config_t twi_config = {
.scl = 27,
.sda = 26,
.interrupt_priority = APP_IRQ_PRIORITY_HIGH
};
//err_code = nrf_drv_twis_init(&m_twi, &twi_config, twis_event_handler);
err_code = nrf_drv_twis_init(&m_twi, &twi_config, NULL);
APP_ERROR_CHECK(err_code);
nrf_drv_twis_enable(&m_twi);
}
/**@brief Handle events from button timer.
*
* @param[in] p_context parameter registered in timer start function.
*/
static void m_timer_handler(void * p_context)
{
uint16_t count=0;
char txbuffer[32];
strcpy(txbuffer, "ready!\n");
uint16_t len=strlen(txbuffer);
NRF_LOG_INFO("Sending Data: %d.", len);
ret_code_t err_code = nrf_drv_twis_tx_prepare(&m_twi, txbuffer, len);
APP_ERROR_CHECK(err_code);
while(nrf_drv_twis_is_pending_tx(&m_twi) && count<350)
{
nrf_delay_ms(1);
count++;
}
NRF_LOG_INFO("Loop hops: %d.", count);
}
int main(void)
{
// Initialize.
log_init();
twi_init();
uint32_t timeout_ticks = APP_TIMER_TICKS(500);
ret_code_t err_code = app_timer_create(&m_bsp_tmr, APP_TIMER_MODE_REPEATED, m_timer_handler);
APP_ERROR_CHECK(err_code);
app_timer_start(m_bsp_tmr, timeout_ticks, NULL);
// Start execution.
printf("BLE UART central example started.\r\n");
NRF_LOG_INFO("BLE UART central example started.");
// Enter main loop.
for (;;)
{
idle_state_handle();
}
}
In SES-debugger, I get:
<info> app_timer: RTC: initialized.
<info> app: BLE UART central example started.
<info> app: Sending Data: 7.
<info> app: Loop hops: 0.
<info> app: Sending Data: 7.
<info> app: Loop hops: 0.
(...)
But measuring shows:
1) SCL is provided with 115k clock from master
2) SDA-PIN shows no activity
Any suggestions on corrections?
Best regards,
Richard