Hello everyone!
I'm trying to use the serial channel of the piccolo, but i'm having some troubles. I want to interrupt the CPU at 3kHz, and, at the interrupt function, send a complete word (10 bits) at 38400 bps. The interrupt is generated by an ePWM. I'm using some code from the TMS320F2808, the ACI3_1 and ACI3_3, (V/Hz and FOC strategies for induction motor control) . The thing is that i should be seeing an 'a' with the hyperterminal, but i'm seeing 'FF'. I'm running the program using the flash.
I'm sure the ePWM interrupt is working properly 'cause i've seen the pins with an oscilloscope, changing duty cycle and frequency. What's wrong with the serial?, can somebody please help me? Thanks in advance!
My code is the following:
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include "IQmathLib.h"
#include "control_v1.h" // This file has the #includes for PWM and SERIAL structure. The PWM is the same as the ACI3_1 project. The SERIAL structure is at the bottom.
#include <math.h>
#pragma CODE_SECTION(MainISR, "ramfuncs");
// Prototype statements for functions found within this file.
interrupt void MainISR(void);
void scia_xmit(int a);
void serial_send(char * msg);
// Global variables used in this system
float32 T = 0.001/3; // Sampling period (sec)
char* msg = "a\0";
// Instance a PWM driver instance
PWMGEN pwm1 = PWMGEN_DEFAULTS;
// Initialize Serial module
SERIAL serial_comm = SERIAL_DEFAULTS;
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
void main(void)
{
// Initialize System Control registers, PLL, WatchDog, Clocks to default state:
// This function is found in the DSP280x_SysCtrl.c file.
InitSysCtrl();
// Globally synchronize all ePWM modules to the time base clock (TBCLK)
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
// Prescale register settings, normally it will be set to default values
EALLOW; // This is needed to write to EALLOW protected registers
SysCtrlRegs.LOSPCP.all = 0x0000; // SYSCLKOUT/1
EDIS; // This is needed to disable write to EALLOW protected registers
// Disable and clear all CPU interrupts: (IER & IFR son registros de la CPU)
DINT; // Disable maskable interrupts
IER = 0x0000; // Interrupt Enable Register: INT1 - INT14 Disabled, RTOSINT & DLOGINT Disabled
IFR = 0x0000; // Interrupt Flag Register:(IDEM) not pending
// Initialize Pie Control Registers To Default State:
// This function is found in the DSP2802x_PieCtrl.c file.
InitPieCtrl();
// Initialize the PIE Vector Table To a Known State:
// This function is found in DSP280x_PieVect.c.
// This function populates the PIE vector table with pointers
// to the shell ISR functions found in DSP280x_DefaultIsr.c.
InitPieVectTable();
// User specific functions, Reassign vectors (optional), Enable Interrupts:
// Reassign ISRs.
// Reassign the PIE vector for EPWM1_INT to point to a different
// ISR then the shell routine found in DSP280x_DefaultIsr.c.
// This is done if the user does not want to use the shell ISR routine
// but instead wants to use their own ISR.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.EPWM1_INT = &MainISR;
EDIS; // This is needed to disable write to EALLOW protected registers
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM
InitFlash();
// Enable CNT_zero interrupt using EPWM1 Time-base
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable EPWM1INT generation
EPwm1Regs.ETSEL.bit.INTSEL = 1; // Enable interrupt CNT_zero event
EPwm1Regs.ETPS.bit.INTPRD = 1; // Generate interrupt on the 1st event
EPwm1Regs.ETCLR.bit.INT = 1; // Enable more interrupts (clear flag)
// Initialize PWM module
pwm1.PeriodMax = 60*1000000*T/2;
pwm1.init(&pwm1);
serial_comm.init(&serial_comm);
/************** Peripherals initialized **************/
// Enable PIE group 3, interrupt 1 for EPWM1_INT
PieCtrlRegs.PIEIER3.all = M_INT1; // 1 en INT3.1
// Enable CPU INT3 for EPWM1_INT: Interrupción 3 queda habilitada
IER |= M_INT3;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM by clearing INTM status bit
ERTM; // Enable Global realtime interrupt DBGM (single steps or breakpoints on ISR)
// IDLE loop. Just sit and loop forever:
for(;;);
}
interrupt void MainISR(void)
{
serial_send(msg);
// Enable more interrupts from this timer
EPwm1Regs.ETCLR.bit.INT = 1;
// Acknowledge interrupt to recieve more interrupts from PIE group 3
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
}
void scia_xmit(int a)
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {}
SciaRegs.SCITXBUF=a;
}
void serial_send(char * msg)
{
int i;
i = 0;
while(msg[i] != '\0')
{
scia_xmit(msg[i]);
i++;
}
}
My serial structure is: (SERIAL.h)
#ifndef __SERIAL__
#define __SERIAL__
/*-----------------------------------------------------------------------------
Define the structure of the SERIAL Object
-----------------------------------------------------------------------------*/
typedef struct { void (*init)(); // Pointer to the init function
} SERIAL;
typedef SERIAL *SERIAL_handle;
#define SERIAL_DEFAULTS { (void (*)(Uint32))serial_init}
void serial_init(SERIAL *p);
#endif // SERIAL
And serial.c:
#include "DSP2802x_Device.h"
#include "SERIAL.h"
void serial_init(SERIAL *p)
{
// Initialize pins
InitSciaGpio();
// Initialize FIFO
/*SciaRegs.SCIFFTX.all=0xE040;
SciaRegs.SCIFFRX.all=0x2044;
SciaRegs.SCIFFCT.all=0x0;*/
/*
SCIFFTX 1110 0000 0100 0000
SCIFFRX 0010 0000 0100 0100
SCIFFCT 0000 0000 0000 0000
*/
// Initialize Serial Mode
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity, 8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.all =0x0003;
SciaRegs.SCICTL2.bit.TXINTENA =1;
SciaRegs.SCICTL2.bit.RXBKINTENA =1;
SciaRegs.SCIHBAUD =0x0000; // 38400 baud @LSPCLK = 15MHz (60 MHz SYSCLK).
SciaRegs.SCILBAUD =0x0030; //
// Relinquish SCI from Reset (after reset system this bit must be set)
SciaRegs.SCICTL1.all =0x0023;
}