This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

20 bit DMA access MSP4305659, intrinsic _data20_write_long()

Other Parts Discussed in Thread: MSP430F5659, CC1101, CC1190

1. Config: MSP430F5659, CCS6, compiler 4.4.3 coffabi, --silicon_version=mspx,

--code_model=large --data_model=large --near_data=none

2. I'm switching from the restricted memory model to the large and having trouble with DMA.

Here is the code snippet that I am having trouble with (this works fine before we exceeded the RAM boundary 0x2400-0x6400 region and are into RAM2 0xf0000 - 0xfc0000):

    _data20_write_long((uintptr_t) &DMA0SA,         // Source: write data pointer.
                       (uintptr_t) dma_request_current->mosi);

The value for dma_request_current->mosi = 0xf61b6.

3. Here is the assembly code copied from the debugger:

442         _data20_write_long((uintptr_t) &DMA0SA,         // Source: write data pointer.
011e10:   432F                MOV.W   #2,R15
011e12:   1F80 525F 619C      ADDX.A  &dma_request_current,R15
011e18:   4F2E                MOV.W   @R15,R14
011e1a:   0F0F                MOVA    @R15,R15
011e1c:   190F 104F           RPT #16   RRUX.A  R15
011e20:   4F0F                MOV.W   R15,R15                                  // NOOP?
011e22:   008D 0512           MOVA    #0x00512,R13
011e26:   4E8D 0000           MOV.W   R14,0x0000(R13)
011e2a:   4F8D 0002           MOV.W   R15,0x0002(R13)

4. As far as I can tell this assembly is perfect. As I single step through the assembly I see that the following registers get set:

R13 = 0x512   // DMA0SA address

R14 = 0x61B6

R15 = 0x000F

In line 011e26: I see DMA0SA is set to 0x61B6

However, line 0011e2a: has no effect!

In the debugger, both using the Register view and Memory Browser I cannot set the upper 4 bits of DMA0SA. It just will not happen. Which explains why assembly line 011e2a has no effect. It should set the upper 4 bits to 0xF.

What is going on here?

  • Note: dma_request_current->mosi is type void*.
  • Hi Nat,

    Is the DMA already running when you do your setting of the DMA0SA register? Please see the MSP430F5659 errata document www.ti.com/.../slaz493 the DMA4 erratum. If you have any DMA transfers going on already, this could potentially cause a problem.

    Regards,
    Katie
  • Hi Nat,

    Looking deeper into this, we see that the generated assembly is using mov.w not movx.w - you need movx.w because you are trying to do a 20-bit write. The DMAxSA register description in www.ti.com/.../slau208 Table 11-11 says "Reading or writing bits 19-16 requires the use of extended instructions. When writing to DMAxSA with word instructions, bits 19-16 are cleared." So that is why mov.w doesn't work - it's doing 16-bit writes and that's causing the upper bits to get cleared.

    Looking at the compiler guide www.ti.com/.../slau132 table 6-5 on p. 131, for __data20_write_long it should generate some different instructions - it should use movx.w which will let you do 20-bit writes. I notice however that it says you should be using the unsigned long type for both parameters that you pass to it, but you appear to be using something else.

    Can you try changing your code to use (unsigned long) instead of (uintprt_t) type for both parameters in your use of _data20_write_long so that it matches the compiler guide? Hopefully then the compiler should generate the correct assembly - please let us know if this works out for you.

    Regards,
    Katie
  • Hi Nat,

    Did this help? Is the issue resolved when you use the unsigned long type for the parameters?

    Regards,
    Katie
  • I will have to go back to that branch and try out your suggestion. That will take a couple of days.
    Thanks - I will try it. For some reason I did not receive a notification for your first 2 replies.
  • Unfortunately, that did not solve the problem. The assembler generated is exactly the same substituting unsigned long in for uintptr_t. This should be expected since uintptr_t is merely a typedef of unsigned long.

    On my file system this is found in C:\ti\ccsv6\tools\compiler\ti-cgt-msp430_4.4.3\include\stdint.h, line 84.
    One other note: I'm using the coff ABI. We have never been able to get EABI working. I don't know if that makes a difference.
  • Hi Nat,

    That's very strange. At this point I'm moving this to the compiler forum to see if they have some ideas about why it's not using movx.w.

    Regards,
    Katie
  • I'm copying in the compiler and linker options used:

    CC ../usci/spi.c
    c:/ti/ccsv6/tools/compiler/ti-cgt-msp430_4.4.3/bin/cl430.exe --compile_only --opt_level=4 --opt_for_speed=3 --define=__MSP430F5659__ --silicon_version=mspx --abi=coffabi --verbose_diagnostics --display_error_number --symdebug:dwarf --define=DEBUG_BUILD --include_path=. --include_path=.. --include_path=c:/ti/ccsv6/ccs_base/msp430/include --include_path=c:/ti/ccsv6/tools/compiler/ti-cgt-msp430_4.4.3/include --include_path=../ti/driverlib/MSP430F5xx_6xx --include_path=../ti --include_path=./usb_config/USB_config --relaxed_ansi --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --code_model=large --data_model=large --near_data=none --printf_support=nofloat --float_operations_allowed=none --emit_warnings_as_errors ../usci/spi.c --output_file=Debug/spi.obj --preproc_with_compile --preproc_dependency=Debug/spi.pp

    LD Debug/fw_sidelinereceiver.out
    c:/ti/ccsv6/tools/compiler/ti-cgt-msp430_4.4.3/bin/cl430.exe --silicon_version=mspx --abi=coffabi --verbose_diagnostics --display_error_number --symdebug:dwarf --define=DEBUG_BUILD --include_path=. --include_path=.. --include_path=c:/ti/ccsv6/ccs_base/msp430/include --include_path=c:/ti/ccsv6/tools/compiler/ti-cgt-msp430_4.4.3/include --include_path=../ti/driverlib/MSP430F5xx_6xx --include_path=../ti --include_path=./usb_config/USB_config --relaxed_ansi --silicon_errata=CPU21 --silicon_errata=CPU22 --silicon_errata=CPU23 --silicon_errata=CPU40 --code_model=large --data_model=large --near_data=none --printf_support=nofloat --float_operations_allowed=none --emit_warnings_as_errors --run_linker --stack_size=1024 --heap_size=0 --use_hw_mpy=F5 --reread_libs --warn_sections --rom_model --section_sizes=on --search_path=c:/ti/ccsv6/tools/compiler/ti-cgt-msp430_4.4.3/lib Debug/interval_timerB0.obj Debug/rtc_interval.obj Debug/watchdog.obj Debug/debug.obj Debug/print_data.obj Debug/strconv.obj Debug/strntol.obj Debug/time_of_day.obj Debug/vprintf.obj Debug/canned_impact_high.obj Debug/canned_impact_low.obj Debug/canned_impact_middle.obj Debug/canned_impact_very_low.obj Debug/canned_impacts.obj Debug/canned_stream.obj Debug/disk_partition.obj Debug/external_flash.obj Debug/id.obj Debug/param.obj Debug/param_defaults.obj Debug/file.obj Debug/filesystem_fixed.obj Debug/stream_file.obj Debug/probe_pins.obj Debug/comm_channel.obj Debug/message_dispatch.obj Debug/message_payload_print.obj Debug/pcd_callbacks.obj Debug/transport_header.obj Debug/transport_layer.obj Debug/transport_stream_print.obj Debug/clocks.obj Debug/hal_pmm.obj Debug/reset.obj Debug/cc1101_agc.obj Debug/cc1101_amplitude.obj Debug/cc1101_config.obj Debug/cc1101_init.obj Debug/cc1101_settings.obj Debug/cc1101_spi.obj Debug/cc1101_state.obj Debug/cc1101_strings.obj Debug/cc1190.obj Debug/freq_hop_common.obj Debug/freq_hop_slr.obj Debug/radio_connection_observer.obj Debug/radio_packet_slr.obj Debug/radio_packet_observer.obj Debug/radio_packet_queue.obj Debug/radio_rate_control_slr.obj Debug/radio_slr_to_mg_info.obj Debug/radio_timer.obj Debug/radio_transport.obj Debug/radio_packet_test.obj Debug/radio_test_cw.obj Debug/radio_test_fcc.obj Debug/radio_test_mod.obj Debug/radio_test_pert.obj Debug/radio_test_runner.obj Debug/self_test.obj Debug/self_test_external_flash.obj Debug/self_test_private.obj Debug/self_test_radio.obj Debug/self_test_results.obj Debug/self_test_stream.obj Debug/isr.obj Debug/scheduler.obj Debug/watchdog_service.obj Debug/usb_cdc.obj Debug/usb_events.obj Debug/usb_hid.obj Debug/usb_init.obj Debug/usb_strings.obj Debug/usb_serial_no.obj Debug/descriptors.obj Debug/UsbIsr.obj Debug/spi.obj Debug/uart_a1.obj Debug/usci.obj Debug/usci_pins.obj Debug/crc.obj Debug/encryption.obj Debug/fifo.obj Debug/hwrev.obj Debug/led.obj Debug/linked_list.obj Debug/memcpy_dma.obj Debug/memory_region_msp430f5659.obj Debug/panic.obj Debug/random.obj Debug/resource_usage.obj Debug/serial_number.obj Debug/simple_parallel.obj Debug/stack_usage.obj Debug/system_pre_init.obj Debug/timed_event.obj Debug/varint.obj Debug/flashctl.obj Debug/gpio.obj Debug/tlv.obj Debug/ucs.obj Debug/./USB_CDC_API/UsbCdc.obj Debug/./USB_Common/usb.obj Debug/./USB_Common/usbdma.obj Debug/./USB_HID_API/UsbHid.obj Debug/./USB_HID_API/UsbHidReq.obj Debug/charger_none.obj Debug/device_cache_print.obj Debug/device_cache_slr.obj Debug/device_cache_stream.obj Debug/filesystem_slr.obj Debug/gpio_interrupts_slr.obj Debug/heartbeat_slr.obj Debug/main_slr.obj Debug/message_handler_slr.obj Debug/pcd_callbacks_slr.obj Debug/power_slr.obj Debug/probe_pins_slr.obj Debug/radio_state_slr.obj Debug/sensor_slr.obj Debug/serial_slr.obj Debug/transport_layer_slr.obj Debug/unused_pins_slr.obj --library=libc.a lnk_msp430f5659.cmd msp430USB.cmd --output_file=Debug/fw_sidelinereceiver.out --map_file=Debug/fw_sidelinereceiver.map
    <Linking>

    FILE: Debug/fw_sidelinereceiver.out

    CODE size (bytes): 73346
    CONST size (bytes): 21761
    DATA size (bytes): 17667

    HEX Debug/fw_sidelinereceiver.txt
    c:/ti/ccsv6/tools/compiler/ti-cgt-msp430_4.4.3/bin/hex430.exe --ti_txt Debug/fw_sidelinereceiver.out --outfile=Debug/fw_sidelinereceiver.txt -order MS -romwidth 16
    Translating to TI-TXT format...
    "Debug/fw_sidelinereceiver.out" .sig ==> .sig
    "Debug/fw_sidelinereceiver.out" .cinit ==> .cinit
    "Debug/fw_sidelinereceiver.out" .text:_isr ==> .text:_isr
    "Debug/fw_sidelinereceiver.out" .const ==> .const
    "Debug/fw_sidelinereceiver.out" USCI_B2 ==> USCI_B2
    "Debug/fw_sidelinereceiver.out" USCI_A2 ==> USCI_A2
    "Debug/fw_sidelinereceiver.out" PORT4 ==> PORT4
    "Debug/fw_sidelinereceiver.out" PORT3 ==> PORT3
    "Debug/fw_sidelinereceiver.out" TIMER2_A1 ==> TIMER2_A1
    "Debug/fw_sidelinereceiver.out" TIMER2_A0 ==> TIMER2_A0
    "Debug/fw_sidelinereceiver.out" DAC12 ==> DAC12
    "Debug/fw_sidelinereceiver.out" RTC ==> RTC
    "Debug/fw_sidelinereceiver.out" PORT2 ==> PORT2
    "Debug/fw_sidelinereceiver.out" USCI_B1 ==> USCI_B1
    "Debug/fw_sidelinereceiver.out" USCI_A1 ==> USCI_A1
    "Debug/fw_sidelinereceiver.out" PORT1 ==> PORT1
    "Debug/fw_sidelinereceiver.out" TIMER1_A1 ==> TIMER1_A1
    "Debug/fw_sidelinereceiver.out" TIMER1_A0 ==> TIMER1_A0
    "Debug/fw_sidelinereceiver.out" DMA ==> DMA
    "Debug/fw_sidelinereceiver.out" USB_UBM ==> USB_UBM
    "Debug/fw_sidelinereceiver.out" TIMER0_A1 ==> TIMER0_A1
    "Debug/fw_sidelinereceiver.out" TIMER0_A0 ==> TIMER0_A0
    "Debug/fw_sidelinereceiver.out" ADC12 ==> ADC12
    "Debug/fw_sidelinereceiver.out" USCI_B0 ==> USCI_B0
    "Debug/fw_sidelinereceiver.out" USCI_A0 ==> USCI_A0
    "Debug/fw_sidelinereceiver.out" WDT ==> WDT
    "Debug/fw_sidelinereceiver.out" TIMER0_B1 ==> TIMER0_B1
    "Debug/fw_sidelinereceiver.out" TIMER0_B0 ==> TIMER0_B0
    "Debug/fw_sidelinereceiver.out" COMP_B ==> COMP_B
    "Debug/fw_sidelinereceiver.out" UNMI ==> UNMI
    "Debug/fw_sidelinereceiver.out" SYSNMI ==> SYSNMI
    "Debug/fw_sidelinereceiver.out" .reset ==> .reset
    "Debug/fw_sidelinereceiver.out" .text ==> .text
  • Nat Ersoz said:

    3. Here is the assembly code copied from the debugger:

    442         _data20_write_long((uintptr_t) &DMA0SA,         // Source: write data pointer.
    011e10:   432F                MOV.W   #2,R15
    011e12:   1F80 525F 619C      ADDX.A  &dma_request_current,R15
    011e18:   4F2E                MOV.W   @R15,R14
    011e1a:   0F0F                MOVA    @R15,R15
    011e1c:   190F 104F           RPT #16   RRUX.A  R15
    011e20:   4F0F                MOV.W   R15,R15                                  // NOOP?
    011e22:   008D 0512           MOVA    #0x00512,R13
    011e26:   4E8D 0000           MOV.W   R14,0x0000(R13)
    011e2a:   4F8D 0002           MOV.W   R15,0x0002(R13)

    It does appear to be a bug in the compiler that the MOVX.W instructions are not used.  Please send a preprocessed source file that includes this problem line.  Also show the entire compiler build command.

  • As I understand it, DMA0SA is in fact in low memory, so you should not use __data20, you should use __data16, and you need to use the addr form:

    __data16_write_addr(&DMA0SA, dma_request_current->mosi);

    Please let us know whether this change fixes your issue.

    If you use __data*_write_long, you are asking for a write of exactly 32 bits, which can only be accomplished with 2 16-bit moves, so it is not an error for the compiler to generate 2 16-bit moves.