|
|
View previous topic :: View next topic |
Author |
Message |
Rocket
Joined: 29 Aug 2005 Posts: 27
|
I feel dumb. |
Posted: Thu Nov 25, 2021 12:31 am |
|
|
I have a problem with writing code for a dsPIC33FJ64MC804.
I need to use SPI, I2C and the UART.
The UART will on occasion have the wrong baud rate, the SPI will fail to start, and the I2C would fail to work. I found that the register values would be wrong. I then proceeded to try and set the registers directly, with limited success.
Compiler: PCD V5.092
IDE: Both MPLAB 8.92 and MPLAB X
With a striped down bit of code, I could get the the simulator to give me the results I expect, but with a REAL ICE and with serial port, the code does not work as I expect it to. I attempted to write values to SPI1STAT, SPI1CON1 and SPI1CON2, end then read them back. Writing to SPI1STAT works. Writing to SPI1CON1 or SPI1CON2 does not.
Results from the MPLAB Sim when reading back the registers:
SPI1STAT: 0x8000
SPI1CON1: 0x1E0E
SPI1CON2: 0xC000
SPI1STAT: 0x0000
SPI1CON1: 0x0000
SPI1CON2: 0x0000
SPI1STAT: 0xA000
SPI1CON1: 0x1E0E
SPI1CON2: 0xC000
SPI1STAT: 0xA000
SPI1CON1: 0x0000
SPI1CON2: 0xC000
Results from the Serial output :
SPI1STAT: 0x8000
SPI1CON1: 0x0000
SPI1CON2: 0x0000
SPI1STAT: 0x0000
SPI1CON1: 0x0000
SPI1CON2: 0x0000
SPI1STAT: 0xA000
SPI1CON1: 0x0000
SPI1CON2: 0x0000
SPI1STAT: 0xA000
SPI1CON1: 0x0000
SPI1CON2: 0x0000
.c File:
Code: |
#include <ABC_Debug.h>
void Print_SPI_Reg_Values(void)
{
unsigned int16 i;
i = SPI1STAT;
fprintf(ESP32,"\nSPI1STAT: 0x%04LX",i);
i = SPI1CON1;
fprintf(ESP32,"\nSPI1CON1: 0x%04LX",i);
i = SPI1CON2;
fprintf(ESP32,"\nSPI1CON2: 0x%04LX\n",i);
}
void Init(void)
{
RST_Cause = restart_cause();
setup_uart(921600, ESP32); // 921600 (227300)
}
#ZERO_RAM
void main()
{
Debug_Var = 1;
Init();
fprintf(ESP32,"RST_Cause = %u: \n\r", RST_Cause);
while(true)
{
SPI1STAT = 0x8000; // SPI Bus Setup
SPI1CON1 = 0x1E0E; // SPI Bus Setup
SPI1CON2 = 0xC000; // SPI Bus Setup
Print_SPI_Reg_Values();
delay_ms(10);
SPI1STAT = 0x0000; // SPI Bus Setup
SPI1CON1 = 0x0000; // SPI Bus Setup
SPI1CON2 = 0x0000; // SPI Bus Setup
Print_SPI_Reg_Values();
delay_ms(10);
SPI1STAT = 0xA000; // SPI Bus Setup
SPI1CON1 = 0x1E0E; // SPI Bus Setup
SPI1CON2 = 0xC000; // SPI Bus Setup
Print_SPI_Reg_Values();
delay_ms(10);
#asm
mov #0x8000, W4
mov W4,0x1E0E // SPI1STAT
mov #0xA000, W4
mov W4,0x0242 // SPI1CON1
mov #0xC000, W4
mov W4,0x0244 // SPI1CON1
#endasm
Print_SPI_Reg_Values();
// Print_UART_Reg_Values();
fprintf(ESP32,"\n\r");
delay_ms(1000);
}
}
|
.h File
Code: |
#include <33FJ64MC804.h>
#device ADC=12
#device ICD=TRUE
#device ICSP=2
#use delay(clock=80MHz,crystal=10MHz)
#pin_select U1TX=PIN_B12
#pin_select U1RX=PIN_B13
#use rs232(UART1, BAUD=921600, errors, stream=ESP32)
#WORD U1BRG = 0x228
#WORD U1MODE = 0x220
#WORD U1STA = 0x222
#FUSES NOWRTB //Boot block not write protected
#FUSES NOBSS //No boot segment
#FUSES NOWRT //Program memory not write protected
#FUSES NOPROTECT //Code not protected from reading
#FUSES PR_PLL //Primary Oscillator with PLL
#FUSES HS //High speed Osc (>10Mhz for PCD)
#FUSES NOOSCIO //OSC2 is clock output
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES WINDIS //Watch Dog Timer in non-Window mode
#FUSES WDT //Watch Dog Timer
#FUSES WPRES32 //Watch Dog Timer PreScalar 1:32
#FUSES WPOSTS16 //Watch Dog Timer PostScalar 1:32768
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES IOL1WAY //Allows only one reconfiguration of peripheral pins
#FUSES PUT128 //Power On Reset Timer value 128ms
#FUSES NOALTI2C1 //I2C1 mapped to SDA1/SCL1 pins
#FUSES LPOL_HIGH //Low-Side Transistors Polarity is Active-High (PWM 0,2,4 and 6)
#FUSES HPOL_HIGH //High-Side Transistors Polarity is Active-High (PWM 1,3,5 and 7)
#FUSES NOPWMPIN //PWM outputs drive active state upon Reset
#FUSES NOJTAG //JTAG disabled
//#use STANDARD_IO( B )
#use FIXED_IO( A_outputs=PIN_A10,PIN_A9,PIN_A8,PIN_A4 )
#use FIXED_IO( B_outputs=PIN_B15,PIN_B14,PIN_B12,PIN_B8,PIN_B7,PIN_B4 )
#use FIXED_IO( C_outputs=PIN_C7,PIN_C6,PIN_C5,PIN_C4,PIN_C0 ) // PIN_C4 = AD7799 Chip Select; C5 is not used for AD7799
#define isodd(x) ((x)&0x001L)
#define On 1
#define Off 0
unsigned int Debug_Var;
//unsigned int RST_Cause;
//unsigned int TempVal16;
unsigned int Debug_Var1;
unsigned int RST_Cause;
unsigned int Tempval16;
#WORD SPI1STAT = 0x240
#WORD SPI1CON1 = 0x242
#WORD SPI1CON2 = 0x244
|
_________________ J.I.L. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
|
Posted: Thu Nov 25, 2021 7:41 am |
|
|
I doubt if your problem is actually with the SPI registers. Much more likely,
you have a clock problem. This would explain the UART baud being wrong.
Depending on what is happening at startup, it could then create problems
with register settings.
Move the #USE RS232 to after the fuses. Sequence should really be:
Processor include.
Fuses
Clock statement
Peripheral setup.
Having the fuses in front of the clock statement then prevents the clock
settings from being changed by the fuses.
Get rid of the clock setup lines in your fuses. The clock statement is already
setting these, and these could override what is being done. Then add
PUT64 to the fuses. This delay is 'essential' when using a crystal, and on this
chip has programmable times 64mSec is a sensible value to try.
On your register settings, you must set the MSTEN bit _before_ you set the
SPIEN bit. Ideally disable the SPIEN bit, do the other settings, then set
the SPIEN bit. Personally though I'd expect the compiler to be setting these
all correctly I think what is happening is it is trying to setup the peripheral
when the clock is not yet stable.
Try adding 'NOINIT' to your #use SPI, then once the chip has booted and
the clock is stable add:
spi_init(SPI_STREAM_NAME,TRUE);
You don't show your current #use SPI statement, so I have made up a
stream name.
Your compiler does have a few issues (in particular a maths problem),
but should work correctly. |
|
|
Rocket
Joined: 29 Aug 2005 Posts: 27
|
|
Posted: Fri Nov 26, 2021 3:23 am |
|
|
Thank you Ttelmah for your reply, I am in the process of implementing the changes you have suggested.
However, regarding my inability to change some of the registers is very puzzling to me. Do you have a comment on why that part of the code works in the simulator, but not in the chip?
Thank you in advance. _________________ J.I.L. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19495
|
|
Posted: Fri Nov 26, 2021 3:35 am |
|
|
The chip only allows you to change those registers when the peripheral is
disabled. The simulator is too thick to know this.
Simulators generally get less than 90% of such things 'right' |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|