Author Topic: ATSAMC21 Rx Buffer Issues  (Read 763 times)

0 Members and 1 Guest are viewing this topic.

Offline dmerry03Topic starter

  • Newbie
  • Posts: 7
  • Country: us
ATSAMC21 Rx Buffer Issues
« on: December 16, 2022, 02:18:31 pm »
Hello all,
 
I am currently developing an ATSAMC21 (SAMC21 Xplained development board) MCU to listen to CAN messages. I am developing on Embedded Workbench for ARM by IAR, and I am writing in strictly Assembly. I am having no trouble compiling or running my code. I have configured (or at least tried to) the MCU in such a way that I have two filter elements, and the frames matching these filter elements get stored into Rx Buffers in RAM. I have even made it so my Rx Buffers are located at the beginning of RAM (Addr: 0x2000'0000). I have tried to keep it as simple as possible and disabled all transmission of data, as well as the Rx FIFO's. My GCLK serving the CAN peripheral is configured at 16Mhz, from the 48MHz internal oscillator. The CAN bus is set for 500Kb/s, no 29-bit headers, no CAN-FD.
 
Now when I send a simple CAN frame, sometimes it will store the message without any issue. But then at other times, it will flip the data received into the buffers. Example below.
 
Frame Sent         Data
0x123                 11 22 33 44 55 66 77 88
 
Data Received
Address
0x20000000         Buffer Register 1
0x20000004         Buffer Register 2
0x20000008         44 33 22 11
0x2000000C         88 77 66 55
 
And then after sending the same message a random number of times, the data will be stored as:
 
Address
0x20000000         Buffer Register 1
0x20000004         Buffer Register 2
0x20000008         88 77 66 55
0x2000000C         88 77 66 55
 
Or it will be stored as:
0x20000000         Buffer Register 1
0x20000004         Buffer Register 2
0x20000008         88 77 66 55
0x2000000C         44 33 22 11
 
When the data comes in erroneously as in method 2 and 3, the CAN0_IR.MRAF bit will be set. I never enabled this interrupt, but it sets itself regardless. I am following the Rx Buffer Handling procedure detailed on page 614 of the datasheet. And I cannot understand the register description of the CAN0_IR.MRAF bit.
 
My CAN0 setup and interrupt are attached.
 
Link to the datasheet here: https://ww1.microchip.com/downloads/aemDocuments/documents/MCU32/ProductDocuments/DataSheets/SAM-C20-C21-Family-Data-Sheet-DS60001479J.pdf
I have given it a good read, at least the parts that I am trying to understand.
 
Can anyone tell me if I am missing something in my setup?
 

Offline dmerry03Topic starter

  • Newbie
  • Posts: 7
  • Country: us
Re: ATSAMC21 Rx Buffer Issues
« Reply #1 on: December 16, 2022, 02:20:46 pm »
File didn't attach the first time. I tried again here. Otherwise code is below:


oscillator_set
  LDR   R1,=OSCCTRL_OSC48MCTRL
  LDR   R0,=0x00070282  ;...1014:0x82 - On Demand | Enable Oscillator
  STR   R0,[R1]         ;...1015:0x02 - 0010 div = 16MHz
                        ;...1016:0x07 - 1024 Clock Cycle Startup (64us)

clock_gen_set_1
  LDR   R1,=GCLK_SYNCBUSY ;Load the SYNCBUSY Status
  LDR   R0,[R1]
  LDR   R2,=0x00000008    ;Look at bit 3
  ANDS  R0,R0,R2          ;If bit 3 is set,
  BNE   clock_gen_set_1   ;then check the SYNC status again
  LDR     R0,=0x00000306    ;else
  LDR   R1,=GCLK_GENCTRL1 ;Enable Generator 1
  STR   R0,[R1]

  ;Attach CAN0 to GCLK1
  LDR   R1,=GCLK_PCHCTRL26_CAN0
  LDR   R0,=0x000000C1
  STR   R0,[R1]

;*******************************************************************************
; CAN 0 Setup
;*******************************************************************************
can0_set
  ;Read the AHBMASK Register and modify it to enable CLK_CAN0_AHB
  LDR   R1,=MCLK_AHBMASK
  LDR   R0,[R1]
  LDR   R2,=0000'0000'0000'0000'0000'0001'0000'0000B
  ORRS  R0,R0,R2
  STR   R0,[R1]

  ;Enable Line 15 of the NVIC
  LDR   R1,=NVIC_ISER
  LDR   R0,=0000'0000'0000'0000'1000'0000'0000'0000B
  STR   R0,[R1]

  ;Enable CAN0 Register Configuration
  LDR   R1,=CAN0_CCCR
  LDR   R0,=0000'0000'0000'0000'0000'0000'0000'0011B
  STR   R0,[R1]

  ;Enable Bus Monitoring Mode
  LDR   R0,=0000'0000'0000'0000'0000'0000'0010'0011B
  STR   R0,[R1]

  ;Configure Quality of Service
  LDR   R1,=CAN0_MRCFG
  LDR   R0,=0000'0000'0000'0000'0000'0000'0000'0011B
  STR   R0,[R1]

  ;Configure Data Bit Timing and Prescaler
  LDR   R1,=CAN0_DBTP
  LDR   R0,=0000'0000'0000'0001'0000'0101'1000'0011B
  STR   R0,[R1]

  ;Configure Nominal Bit Timing and Prescaler
  LDR   R1,=CAN0_NBTP
  LDR   R0,=0000'0110'0000'0001'0000'1010'0000'0011B
  STR   R0,[R1]

  ;Configure Enabled CAN Interrupts
  ;XXXXXXXXXXXXXXXXX MAY NEED TO CHANGE THIS XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  LDR   R1,=CAN0_IE
  LDR   R0,=0000'0000'0000'1000'0000'0000'0000'0000B
  STR   R0,[R1]

  ;Enable CAN Interrupt Line 0
  LDR   R1,=CAN0_ILE
  LDR   R0,=0000'0000'0000'0000'0000'0000'0000'0001B
  STR   R0,[R1]

  ;Standard Frame ID Filtering
  ;Reject remote frames and non-matching frames
  LDR   R1,=CAN0_GFC
  LDR   R0,=0000'0000'0000'0000'0000'0000'0011'1111B
  STR   R0,[R1]

  ;Number of filter elements: 2
  ;Filter List Start Address:
  LDR   R1,=CAN0_SIDFC
  ;Load the address of filter element 0
  LDR   R0,=can0_sf0
  LDR   R2,=0x20000000
  SUBS  R0,R0,R2
  ;Filter elements number specification: 2
  LDR   R2,=0000'0000'0000'0010'0000'0000'0000'0000B
  ORRS  R0,R0,R2
  STR   R0,[R1]

  ;Configure the Rx Buffer
  LDR   R1,=CAN0_RXBC
  ;Load the address of Rx Buffer 0
  LDR   R0,=can0_rxb0_0
  LDR   R2,=0x20000000 ;Start of RAM
  SUBS  R0,R0,R2
  STR   R0,[R1]

  ;Rx buffer is already set to 8-Byte data field
  ;Rx Buffer / FIFO Element Size Configuration
  ;LDR   R1,=CAN0_RXESC
  ;LDR   R0,=0000'0000'0000'0000'0000'0000'0000'0000B
  ;STR   R0,[R1]

  ;Enable CAN0 and Lock Configuration Registers
  LDR   R1,=CAN0_CCCR
  LDR   R0,=0000'0000'0000'0000'0000'0000'0000'0000B
  STR   R0,[R1]



;*******************************************************************************
; Initialize RAM Variables
;*******************************************************************************
can0_filter_set
  ;Standard ID Filter Element 0
  ;[31:30] = Classic Filter                        => 10B
  ;[29:27] = Store into Rx Buffer (Ignore [31:30]) => 111B
  ;[26:16] = Frame ID: 0x123                       => 001'0010'0011B
  ;[15:11] = Reserved                              => 0'0000B
  ;[10:9]  = Store into an Rx Buffer               => 00B
  ;[8:6]   = Event pin                             => 000B
  ;[5:0]   = Buffer Element Number: 0              => 00'0000B
  LDR   R0,=1011'1001'0010'0011'0000'0000'0000'0000B
  LDR   R1,=can0_sf0
  STR   R0,[R1]

;*******************************************************************************
;*******************************************************************************
;*******************************************************************************
; Beginning of MAIN Code
main

  B main
 
;*******************************************************************************
; CAN0 Interrupt Routine
;*******************************************************************************
CAN0_Handler
__can0_handler

  CPSID I
  ;Clear the interrupt flags
  LDR   R4,=CAN0_IR
  LDR   R3,=0000'0000'0000'1010'0000'0000'0000'0000B
  STR   R3,[R4]

  ;Clear the new data in buffer flags
  LDR   R4,=CAN0_NDAT1
  LDR   R3,=0xFFFFFFFF
  STR   R3,[R4]

  ;Read the messages from RAM
  LDR   R4,=my_RAM_variable
  LDR   R3,=0x0
  STR   R3,[R4]
  LDR   R7,=can0_rxb0_2
  LDR   R6,[R7]
  LDR   R5,=0x44332211
  CMP   R6,R5
  BNE   can0_handler_exit
  LDR   R3,=0xFFFFFFFF
  STR   R3,[R4]

can0_handler_exit
  ;Clear the new data in buffer flags
  LDR   R4,=CAN0_NDAT1
  LDR   R3,=0xFFFFFFFF
  STR   R3,[R4]

  CPSIE I
  BX    LR
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf