Jump to content

    

TMS320VC5507, прерывания

подскажите как правильно прерывания у TMS320VC5507 инициализировать.

отладчика нет, что там происходит - непонятно.

interrupt void timer0_isr(void){
  pin_toggle(PIN);
  //clear flag
}

int main(void){
  IVPD = 0x01FF;  //0x01FF00 последние 256байт SARAM
  IVPH = 0x01FF;
 
  *((uint32_t *)(0x01FF20)) = (uint32_t)&timer0_isr; //0x20 смещение прерывания таймера
  *((uint16_t *)(0x01FF22)) = 0x2020; //NOP, NOP??  
  
//  *((uint32_t *)(0x01FF22)) = 0x5E805E80; //NOP16, NOP16?? 


  IER0 |= (1<<4);  
  _enable_interrupts();

  PRSC0 = 0x0F;
  PRD0 = 0xFFFF;
  TCR0 = (1<<5);  //ABR
  // таймер побежал, но по переолнению через ~10мс оказывамся хз где, а не в обработчике прерывания.
  
  while(1);
  return 0;
}

и почему в таблицу пишется именно адрес (а не jmp адрес) но при этом оставшееся место забивается NOPами?

 

irq_plug из csl:

;* ============================================================================
;* Copyright (c) 2008-2012 Texas Instruments Incorporated.  
;* 
;*  Redistribution and use in source and binary forms, with or without
;*  modification, are permitted provided that the following conditions
;*  are met:
;*
;*    Redistributions of source code must retain the above copyright
;*    notice, this list of conditions and the following disclaimer.
;*
;*    Redistributions in binary form must reproduce the above copyright
;*    notice, this list of conditions and the following disclaimer in the
;*    documentation and/or other materials provided with the
;*    distribution.
;*
;*    Neither the name of Texas Instruments Incorporated nor the names of
;*    its contributors may be used to endorse or promote products derived
;*    from this software without specific prior written permission.
;*
;*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
;*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
;*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
;*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
;*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
;*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
;*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
;*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
;*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
;*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
;*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*
;*/

; Module: INTC
; Function: IRQ_PLUG
; File: csl_irqplug.asm
;
;
;--------------------------------------------------------
; Description:
;   This function writes the address of the given ISR into
; the correct location in the interrupt vector table.
;
; Arguments:
;     T0 - contains EventId of associated vector
;     AC0 - contains address of ISR
;
; Local Function Variables:
;     SP(#0)   - location in vector table where ISR address
;                needs to be placed
;     SP(#2)   - ISR function address
;     SP(#4)   - IVPD pointer value
;     SP(#5)   - Bit in IER corresponding to event
;     SP(#6)   - Mask used to clear event in IFR
;     SP(#7)   - EventId
;     SP(#8)   - old_intm, old value of INTM bit
;////////////////////////////////////////////////////////
	.asg 123, CSL_DATA_PTR
	.asg 05E80h, NOP16_Operator
	.asg 0, VecLoc
	.asg 2, IsrAddr
	.asg 4, Iptr
	.asg 5, EventBit
	.asg 6, EventMask
	.asg 7, EventId
	.asg 8, Old_INTM
	.asg 9, LocalFrameSz
	.asg 12, BiosPresentFlag
	.asg 049h, IVPD_ADDR
	.asg 04Ah, IVPH_ADDR
	.asg 001h, IFR0_ADDR
	.asg 046h, IFR1_ADDR

	.mmregs

	.def _IRQ_plug

	.ref _IRQ_globalDisable
	.ref _IRQ_globalRestore
	  .cpl_on
_IRQ_plug:
      PSHBOTH(XAR3)
      PSHBOTH(XAR2)
      SP = SP - #LocalFrameSz          ; Reserve local space
      dbl(*SP(#IsrAddr)) = AC0         ; Store ISR function address
      *SP(#EventId) = T0               ; Store EventId
      AC0 = #0                         ; Clear XAR2/XAR3
      XAR2 = AC0                       ;
      XAR3 = AC0	                   ;

      CALL _IRQ_globalDisable          ; Disable Interrupts
      *SP(#Old_INTM) = T0              ; Save OLD VALUE of INTM
      NOP
      NOP
      NOP
      NOP
      NOP
      XAR2 = #IVPD_ADDR                ; Get IVPD value
      NOP
      NOP
      NOP
      NOP
      NOP
      AC1 = *SP(#EventId)              ; EventId Gets placed in AC1

      AC3  = AC1 & #018h               ; Check for ISRs 16-23
      AC3 = AC3 - #16                  ; If ISR is 16-23 then use
      if (AC3 == 0) execute (AD_UNIT)  ; IVPH value for determining
      XAR2 = #IVPH_ADDR                ; vector address

      AC1 = AC1 << #3                  ; Multiply EventId by 8 to get Vector Offset          
      AC0 = *AR2                       ; AC0 should now have IVPD value
      AC0 = AC0 <<  #4                 ; Shift up to get Vector Base Address
   	  AC0 = AC0 <<  #4                 ; Shift up to get Vector Base Address
      AC0 = AC0 | AC1                  ; AC0 now has Vector Address
      AC0 = AC0 << #-1                 ; Shift to get word address
      dbl(*SP(#VecLoc)) = AC0          ; Store Vector Address
      AC0 = dbl(*SP(#IsrAddr))         ; AC0 now has ISR address
      XAR3 = dbl(*SP(#VecLoc))         ; XAR3 has Vector Address
      AR1 = *SP(#EventId)              ; AR1 gets EventId
      AR2 = AR1 & #15                  ; Get only lower bits
      dbl(*AR3) = AC0                  ; Store ISR address at Vector Location
      AC3 = NOP16_Operator             ; Load NOP instruction into AC3
      AR3 += 2                         ; Set byte address to next location
      *AR3 = AC3                       ; Plug remaining part of vector with nop
      AR3 += 1                         ; Increment to next part of vector location
      *AR3 = AC3                       ; Plug remaining part of vector with nop
      T0 = AR2                         ; Use lower Bits as shift value
      AR1 = AR1 & #16                  ; Check to see if event is flagged in IFR1
      AC0 = #1                         ; Set AC0 = 1
      AC0 = AC0 <<< T0                 ; Shift AC0 by Bit value
      AC3 = AC0                        ; This is mask for IFR

      if (AR1 != #0) goto LIFR1        ; IF AR1 != 0, mask IFR1
      AR2 = #IFR0_ADDR                 ; Point AR2 to IFR0
      *AR2 = AC3                       ; Mask IFR0
      goto RESTORE_INTM
LIFR1:
      AR2 = #IFR1_ADDR                 ; Point AR2 to IFR1
      *AR2 = AC3                       ; Mask IFR1
RESTORE_INTM:
      T0 = *SP(#Old_INTM)              ; Set T0 to old INTM Value
      CALL _IRQ_globalRestore          ; Call IRQ function to restore old_intm
EPILOGUE:
      SP = SP + #LocalFrameSz          ; Restore Stack Pointer
      XAR2 = POPBOTH()                 ; POP XAR regs
      XAR3 = POPBOTH()
      RETURN

 

Share this post


Link to post
Share on other sites
13 часов назад, _pv сказал:

подскажите как правильно прерывания у TMS320VC5507 инициализировать.

Также как в других МК - инициализировать периферию и разрешить прерывание.

Цитата

и почему в таблицу пишется именно адрес (а не jmp адрес) но при этом оставшееся место забивается NOPами?

Не знаю где забивается NOP-ами, я забивал переходами на затычку. Файл описания таблицы векторов из проекта для VC5502: cc5502_ivecs.rar

А вообще - у TI вполне полная документация, в которой описан формат таблицы векторов прерываний.

Share this post


Link to post
Share on other sites

спасибо, а можно ещё скрипт линкера оттуда же?

 

TMS320C55x DSP CPU Reference Guide

Quote

You must write the desired interrupt vectors (ISR start address) at the vector addresses. Each interrupt vector must contain 8 bytes. Byte 0 of the reset vector contains the setting for the stack mode. Byte 0 of the remaining vectors is ignored. Bytes 1−3 encode the 24-bit byte address of the interrupt service routine (ISR). Bytes 4−7 must be filled with NOP instructions.

 

 

Share this post


Link to post
Share on other sites
29 минут назад, _pv сказал:

спасибо, а можно ещё скрипт линкера оттуда же?

cc5502_cmd.rar

В строке ".ivec _c_int00, c54x_stk" у меня как раз и задаётся точка входа по сбросу и верхушка стека. Определены они внутри rts.lib

Также писал и отлаживал тот проект без эмулятора.

 

Share this post


Link to post
Share on other sites

оказался слишком тупым, чтобы совладать с линкером, сделал как в CSL, с размещением обработчиков в таблицу руками.

грабли были с адресацией, в IVPD адрес в байтах, а не словах.

в результате запись обработчика в таблицу должна выглядеть так:

*((volatile uint32_t *)((IVPD << 7) + (4 << 2))) = ((uint32_t)&timer0_isr);  //SINT4=TINT0, byte offset 0x20, word offset 0x10
 

Share this post


Link to post
Share on other sites
6 часов назад, _pv сказал:

оказался слишком тупым, чтобы совладать с линкером, сделал как в CSL, с размещением обработчиков в таблицу руками.

А мой файл не принимает что-ль?

Скомпилил сейчас тот старый проект - всё ок. vectors.lst:

      41 ****** MACRO           .asgn     ISRdmac, irqCodecDMA, _ISRcodec
      41                            .eval     irqCodecDMA, num
      41                            .asg      _ISRcodec, ISRdmac0
      42              ;          .asgn     ISRtint, irqTimer, _ISRtimer
      43
      44 000000                 .sect     ".vectors"
      45                        .align    256
      46 000000 EA    _VECSTART:.ivec     _c_int00, c54x_stk  ;00 RESET
         000001 0000
         000003 00%
      47 000008 EA              .ivec     ISRnmi              ;01 NMI
         000009 0000
         00000b 00%
      48 000010 EA              .ivec     ISRint0             ;02 INT0
         000011 0000
         000013 00%
      49 000018 EA              .ivec     ISRint2             ;03 INT2
         000019 0000
         00001b 00%
      50 000020 EA              .ivec     ISRtint0            ;04 TINT0
         000021 0000
         000023 00%
...

И .map:

OUTPUT FILE NAME:   <DEBUG.OUT/mr04.out>
ENTRY POINT SYMBOL: "_c_int00"  address: 00009dac


MEMORY CONFIGURATION

                  name            origin    length      used    attr    fill
                                 (bytes)   (bytes)    (bytes)
         ----------------------  --------  ---------  --------  ----  --------
PAGE  0: MMR                     00000000   000000c0  00000000  RWI
         DARAM0                  00000100   00001f00  00001bdf  RWIX
         DARAM1                  00002000   00002000  00002000  RWIX
         DARAM2                  00004000   00005e00  00005dfe  RWIX
         DARAM6                  00009e00   00000200  000000f8  RWIX
         DARAM7                  0000a000   00005ffc  00005ad7  RWIX
         DARAM8                  0000fffc   00000004  00000000  RWIX

PAGE  2: IOPORT                  00000000   0000ffff  00000000  RWI


SECTION ALLOCATION MAP
(Addresses surrounded by []'s are displayed for convenience only!)

output                                                          attributes/
section   page  orgn(bytes) orgn(words) len(bytes) len(words)   input sections
--------  ----  ----------- ----------- ---------- ----------   --------------
.bss0        0   [ 00000100 ]  00000080          *   00000220   UNINITIALIZED
                 [ 00000100 ]  00000080          *   00000220   modem.obj (.bssDMA)

.cinit       0   [ 00000540 ]  000002a0          *   00000025
                 [ 00000540 ]  000002a0          *   00000018   line.obj (.cinit)
                 [ 00000570 ]  000002b8          *   00000008   main.obj (.cinit)
                 [ 00000580 ]  000002c0          *   00000004   config.obj (.cinit)
                 [ 00000588 ]  000002c4          *   00000001   --HOLE-- [fill = 0]

.text0       0     0000058a  [ 000002c5 ] 00000055          *
                   0000058a  [ 000002c5 ] 00000054          *   init.obj (.text)
                   000005de  [ 000002ef ] 00000001          *   --HOLE-- [fill = 20]

.vectors     0     00000600  [ 00000300 ] 00000100          *
                   00000600  [ 00000300 ] 00000100          *   vectors.obj (.vectors)

.bss1        0   [ 00000700 ]  00000380          *   00000b00   UNINITIALIZED
                 [ 00000700 ]  00000380          *   00000b00   line.obj (.bssSlowAccess)
...

 

6 часов назад, _pv сказал:

в результате запись обработчика в таблицу должна выглядеть так:

*((volatile uint32_t *)((IVPD << 7) + (4 << 2))) = ((uint32_t)&timer0_isr);  //SINT4=TINT0, byte offset 0x20, word offset 0x10

У меня в runtime вектора не писались. Они были константами - грузились штатным ROM-загрузчиком из флешки (или UART).

Share this post


Link to post
Share on other sites

линкер по какой-то причине не видит обработчики из vectors, и наоборот из main не видит VECSTART, поковырялся, плюнул и в результате просто руками поменял IVPD и таблицу в рантайме. ну а при загрузке ресет делает через дефолтную таблицу в ROM.

у меня тут ещё другие чудеса, при добавлении в проект примитивного класса фифо с шаблонами, ломается !USB загрузчик! то есть просто перестаёт принимать бинарную прошивку на середине, если убрать template - всё хорошо.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this