|
|
View previous topic :: View next topic |
Author |
Message |
PeWa
Joined: 15 Jan 2019 Posts: 22 Location: Sweden
|
dsPIC30F4011 setup_spi and #use spi parameters |
Posted: Sat May 01, 2021 11:20 am |
|
|
I have some problem to manually set spi parameters it does not work
I am copying a spi transfer from another circuit and I try to build the
same data and clock.
The clock shift is now right ON the data shift trigger on rising so i got some numbers error, then I saw that I could set the width manually so
am trying to set the clock width as a longer low and a shorter high.
If the #use parameters had worked I could just set the data to trigger on
falling edge and not needed the width.
It's quite a simple test program where I send out 6 pair of 4 x 8 byte.
MCU is a 30F4011 and compiler is 5.076
No matter what I set in the #use parameter it does not take action.
If I omit the setup_spi in main the program get stuck in first spi_write
so it does not seem to read the #use spi parameters.
The timer is only toggle a led for program run indication.
Am i missing something ? The whole program is below here:
Code: |
#FUSES BORRES //Reserved (do not use)
#FUSES NOBROWNOUT //No brownout reset
#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 MCLR //Master Clear pin enabled
#FUSES NOWRT //Program memory not write protected
#FUSES NOPROTECT //Code not protected from reading
#use delay(internal=7370000)
//#use spi(MASTER, SPI1, MODE=0, BITS=8,FORCE_SW,CLOCK_HIGH=85,CLOCK_LOW=254)
#use spi(Master, SPI1, force_sw, CLK=PIN_F6, DO=PIN_F3, mode = 0, msb_first, bits=8,CLOCK_HIGH=85,CLOCK_LOW=170)
#include <main.h>
int16 tmr1time = 0;
int1 tmr1flag = 0;
char sendVFO1[4]= 0x00,0x58,0x00,0x05;
char sendVFO2[4] = 0x00,0xA8,0xF6,0x3C;
char sendVFO3[4] = 0x00,0x04,0x00,0x03;
char sendVFO4[4] = 0x20,0x01,0xFE,0x42;
char sendVFO5[4] = 0x00,0x00,0x80,0x09;
char sendVFO6[4] = 0x00,0x70,0x00,0x00;
#INT_TIMER1
void timer1_isr(void)
{
if(tmr1time++ <= 500)
{
tmr1flag = 1;
}
}
void main()
{
int count;
output_high(PIN_B0);
setup_timer1(TMR_INTERNAL | TMR_DIV_BY_256, 3003);
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_320);
enable_interrupts(INT_TIMER1);
enable_interrupts(INTR_GLOBAL);
delay_ms(500);
output_low(PIN_B0);
delay_us(175);
for(count=0; count <= 3; count++)
{
spi_write(sendVFO1[count]);
}
output_high(PIN_B0);
delay_us(440);
output_low(PIN_B0);
for(count=0; count <= 3; count++)
{
spi_write(sendVFO2[count]);
}
output_high(PIN_B0);
delay_us(440);
output_low(PIN_B0);
for(count=0; count <= 3; count++)
{
spi_write(sendVFO3[count]);
}
output_high(PIN_B0);
delay_us(440);
output_low(PIN_B0);
for(count=0; count <= 3; count++)
{
spi_write(sendVFO4[count]);
}
output_high(PIN_B0);
delay_us(440);
output_low(PIN_B0);
for(count=0; count <= 3; count++)
{
spi_write(sendVFO5[count]);
}
output_high(PIN_B0);
delay_us(440);
output_low(PIN_B0);
for(count=0; count <= 3; count++)
{
spi_write(sendVFO6[count]);
}
output_high(PIN_B0);
while(TRUE)
{
if(tmr1flag == 1)
{
output_toggle(PIN_B1);
tmr1flag = 0;
tmr1time = 0;
}
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19509
|
|
Posted: Sun May 02, 2021 12:31 am |
|
|
Big problem is the parameters you are trying to use in #USE SPI. The SPI
hardware cannot support separate times for the high and low parts of the
cycle. Look at the data sheet. The only control is the actual clock rate.
Separate high and low times are only supported on a software SPI, but
you are explicitly selecting a hardware port. This makes the #USE setup
not work correctly...
You can't specify 'SPIx', and 'FORCE_SW'. Selecting SPIx, says _use the
internal SPI peripheral x_. If you want to use FORCE_SW, you have to
specify what pins you want, not the SPI peripheral.
No SPI device should ever need different times for the high and low clocks.
SPI always transfers on one clock edge only, so it is the total period, and
which edge is used for the output and input transfers that matter.
Then a second thing that I have pointed out many times. If you look in the
manual for #USE SPI, look at the bottom of the page. What SPI functions
does it say associate with this?. You will not find SPI_read or SPI_write here.
Basically there are two sets of SPI functions:
setup_spi, spi_read and spi_write, which are the 'older' functions, and only
support hardware SPI. Then there are the newer functions #USE SPI, with
spi_xfer, spi_transfer_write, spi_transfer_read etc.. Generally you should
never mix operations from the two sets. Either just use #USE and the xfer
functions, or use setup with the read/write functions. Mixing can occasionally
work, but is not really supported, and 99% of the time gives problems.
Using spi_read and spi_write means this will always be using the hardware
port, so your attempts at 'FORCE_SW' will not have worked.
With #USE SPI, you should only use spi_xfer, not spi_read and spi_write...
Now, you don't tell us what the 'device' is. If you did, we could find it's
data sheet and see what might be wrong. However data errors, suggest
you are using the wrong clock edge for the output transfer |
|
|
PeWa
Joined: 15 Jan 2019 Posts: 22 Location: Sweden
|
|
Posted: Sun May 02, 2021 2:07 am |
|
|
Ttelmah wrote: | Big problem is the parameters you are trying to use in #USE SPI. The SPI
hardware cannot support separate times for the high and low parts of the
cycle. Look at the data sheet. The only control is the actual clock rate.
Separate high and low times are only supported on a software SPI, but
you are explicitly selecting a hardware port. This makes the #USE setup
not work correctly...
You can't specify 'SPIx', and 'FORCE_SW'. Selecting SPIx, says _use the
internal SPI peripheral x_. If you want to use FORCE_SW, you have to
specify what pins you want, not the SPI peripheral.
No SPI device should ever need different times for the high and low clocks.
SPI always transfers on one clock edge only, so it is the total period, and
which edge is used for the output and input transfers that matter.
Then a second thing that I have pointed out many times. If you look in the
manual for #USE SPI, look at the bottom of the page. What SPI functions
does it say associate with this?. You will not find SPI_read or SPI_write here.
Basically there are two sets of SPI functions:
setup_spi, spi_read and spi_write, which are the 'older' functions, and only
support hardware SPI. Then there are the newer functions #USE SPI, with
spi_xfer, spi_transfer_write, spi_transfer_read etc.. Generally you should
never mix operations from the two sets. Either just use #USE and the xfer
functions, or use setup with the read/write functions. Mixing can occasionally
work, but is not really supported, and 99% of the time gives problems.
Using spi_read and spi_write means this will always be using the hardware
port, so your attempts at 'FORCE_SW' will not have worked.
With #USE SPI, you should only use spi_xfer, not spi_read and spi_write...
ThankĀ“s for input I will check this further
Now, you don't tell us what the 'device' is. If you did, we could find it's
data sheet and see what might be wrong. However data errors, suggest
you are using the wrong clock edge for the output transfer
The MUC is stated in the text above I wrote 30F4011
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19509
|
|
Posted: Sun May 02, 2021 2:25 am |
|
|
No, not the PIC, the device you are trying to clock data to...
Even if it is something like just a CMOS shift register, tell us the part number
and how it is wired, and we can then probably see what the problem is. |
|
|
|
|
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
|