SPI Initialization and JinkGDBServer

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hello,
I'm in the process of figuring out, how to initialize a SPI interface. I'm using a Hexagon Application Kit which has an integrated JLink SWT interface. I use the JLinkDGBServer V4.98e on OSX. This is the function I like to debug:


void init_spi()
{
// unRESET MODULE
SCU_RESET->PRCLR0 |= 1 << SCU_RESET_PRCLR0_USIC0RS_Pos;

// enable clock for USIC0
SCU_CLK->CGATCLR0 |= ( 1 << SCU_CLK_CGATSTAT0_USIC0_Pos );

// switch on modul
channel->KSCFG = ( 1 << USIC_CH_KSCFG_MODEN_Pos ) | ( 1 << USIC_CH_KSCFG_BPMODEN_Pos );

// "After writing 1 to MODEN, it is recommended to read register KSCFG to avoid pipeline effects in the control block before accessing other USIC registers."
volatile std::uint32_t dummy = channel->KSCFG;
static_cast< void >( dummy );

// check that SPI is available
assert( channel->CCFG & ( 1 << USIC_CH_CCFG_SSC_Pos ) );

// clock generation in normal divider mode with f = f_periph / 1024
channel->FDR = ( 1 << USIC_CH_FDR_DM_Pos ) | ( 0 << USIC_CH_FDR_STEP_Pos );
// clock is delayed by 1/2 period
channel->BRG = ( 2 << USIC_CH_BRG_SCLKCFG_Pos );

// Select SSC mode:
// Bit field SCTR.TRM = 01B has to be programmed. WLE = 8 Bit word length (7==8bits)
channel->SCTR =
( 1 << USIC_CH_SCTR_TRM_Pos ) | // enable clock
( 1 << USIC_CH_SCTR_SDIR_Pos ) | // MSB first
( 7 << USIC_CH_SCTR_WLE_Pos );

// MISO Pin Configuration P2.2
channel->DX0CR =
( 0 << USIC_CH_DX0CR_DSEL_Pos ) |
( 1 << USIC_CH_DX0CR_INSW_Pos );

// MOSI Pin Configuration P2.5 as alternativ function 2; output; push-pull
PORT2->IOCR4 = ( PORT2->IOCR4 & ~PORT2_IOCR4_PC5_Msk ) | ( 0x12 << PORT2_IOCR4_PC5_Pos );

// CLOCK Pin configuration P2.4 as alternativ function 2; output; push-pull
PORT2->IOCR4 = ( PORT2->IOCR4 & ~PORT2_IOCR4_PC4_Msk ) | ( 0x12 << PORT2_IOCR4_PC4_Pos );

// CS configuration P2.3 as alternativ function 2; output; push-pull
PORT2->IOCR0 = ( PORT2->IOCR0 & ~PORT2_IOCR0_PC3_Msk ) | ( 0x12 << PORT2_IOCR0_PC3_Pos );

channel->DX2CR =
( 0 << USIC_CH_DX0CR_DSEL_Pos ) |
( 0 << USIC_CH_DX0CR_INSW_Pos );


channel->PCR_SSCMode =
( 0 << USIC_CH_PCR_SSCMode_MSLSEN_Pos ) | // Fixme: SC generation
( 1 << USIC_CH_PCR_SSCMode_MCLK_Pos );

// select protocol SPI
channel->CCR = ( 1 << USIC_CH_CCR_MODE_Pos );
}


As one of the last puzzles solved, I've added the first line of the function that should un-reset the USIC0. But now, if I try to access the channel (equal to USIC0_CH1) with "print/x *channel" from the debugger (gdb), I get the error message "Cannot access memory at address 0x40030200". I can access the peripheral before the first line, but all registers show 0xFFFFFFFF as content.

Is there something apparently wrong with my init function? Is this an issue with the JLinkGDBServer (Error message here is: WARNING: Failed to read memory @ address 0x40030200)?

Thank you very much in advance for any tip or hint!

Edit: I've tried to access individual registers from the channel, and this works find, so I think that the debugging issue is an issue I have to address to segger.

Kind regards,
Torsten
0 Likes
0 Replies