|
|
View previous topic :: View next topic |
Author |
Message |
myloudharim
Joined: 13 Nov 2017 Posts: 10 Location: philly
|
USART to SPI Bridge issues |
Posted: Thu Mar 18, 2021 6:30 pm |
|
|
Hello everybody hopefully you guys doing alright. I'm trying to realize a UART to SPI Bridge but unfortunately my code failed. The thing is UART and SPI work great separately but when to combine them does not work
I'm using ccs c compiler version 4.068.
UART works good but when i uncomment the line #use SPI(SPI1....)
UART does not receive anymore.
Hopefully i can find some help and hopefully this topic will be helpful for people with same project.
Here is my code:
Code: |
#use SPI (SPI1, DO = PIN_C5, DI = PIN_C4, CLK = PIN_C3, BITS = 8, Mode = 0)
//-------------MCP23S17 DEFINES--------------//
#define SPI_DUMMY_DATA 0x00
#define SPI_RX_IN_PROGRESS 0x00
void SPI_Initialize(void)
{
// Set the SPI module to the options selected in the User Interface
// R_nW write_noTX; P stopbit_notdetected; S startbit_notdetected;
//BF RCinprocess_TXcomplete; SMP Middle; UA dontupdate; CKE Active to Idle;
//D_nA lastbyte_address;
SSPSTAT = 0x40;
// SSPEN enabled; WCOL no_collision; CKP Idle:Low, Active:High; SSPM FOSC/64; SSPOV no_overflow;
SSPCON = 0x00;
delay_ms(10);
SSPCON = 0x20;
SSPEN = true; //spi mode
// SSPADD 0;
SSPADD = 0x00;
}
int SPI_Exchange8bit(int data)
{
WCOL = 0; // Clear the Write Collision flag, to allow writing
SSPBUF = data;
while(BF == SPI_RX_IN_PROGRESS)
{
WDTEN = 0x00; //disable watchdog and clears it
}
return (SSPBUF);
}
int SPI_Exchange8bitBuffer(int *dataIn, int bufLen, int *dataOut)
{
int bytesWritten = 0;
if(bufLen != 0)
{
if(dataIn != '\0')
{
while(bytesWritten < bufLen)
{
if(dataOut == '\0')
{
SPI_Exchange8bit(dataIn[bytesWritten]);
}
else
{
dataOut[bytesWritten] = SPI_Exchange8bit(dataIn[bytesWritten]);
}
bytesWritten++;
WDTEN = 0x00; //disable watchdog and clears it
}
}
else
{
if(dataOut != '\0')
{
while(bytesWritten < bufLen )
{
dataOut[bytesWritten] = SPI_Exchange8bit(SPI_DUMMY_DATA);//*****************
bytesWritten++;
WDTEN = 0x00; //disable watchdog and clears it
}
}
}
}
return bytesWritten;
}
int1 SPI_IsBufferFull(void)
{
return (BF);
}
int1 SPI_HasWriteCollisionOccured(void)
{
return (WCOL);
}
void SPI_ClearWriteCollisionStatus(void)
{
WCOL = 0;
}
//**********************************************************
//**********************************************************
#define DEVICE_ADDRESS_WRITE 0x40
#define DEVICE_ADDRESS_READ 0x41
#define IODIRA 0x00 //Data Direction Register for PORTA as output
#define IODIRB 0xFF //Data Direction Register for PORTB as input
#define GPIOA 0x12
#define GPIOB 0x13
#define OLATA 0x14
#define OLATB 0x15
#define IOCON 0x0A //OR 0x15
/**
Section: Macro Declarations
*/
#define OUTPUT_DIR 0x00
#define CS PIN_A2
void CHIP_SELECT_SetLow(){
output_low(CS);
}
void CHIP_SELECT_SetHigh(){
output_high(CS);
}
void MCP23S17_write(int reg, int data) {
CHIP_SELECT_SetLow();
SPI_Exchange8bit(DEVICE_ADDRESS_WRITE);
SPI_Exchange8bit(reg);
SPI_Exchange8bit(data);
CHIP_SELECT_SetHigh();
}
unsigned char MCP23S17_read(unsigned char address)
{
unsigned char received_data = 0;
CHIP_SELECT_SetLow();
SPI_Exchange8bit(DEVICE_ADDRESS_READ);
SPI_Exchange8bit(address);
received_data = SPI_Exchange8bit(0);
CHIP_SELECT_SetHigh();
return received_data;
}
void MCP23S17_Initialize(void) {
MCP23S17_write(IOCON, 0x10);
MCP23S17_write(IODIRA, OUTPUT_DIR);
MCP23S17_write(IODIRB, OUTPUT_DIR);
delay_ms(10);
}
//------------------------------------------------------------------------------
unsigned char mystring[15] ;
//------------------------------------------------------------------------------
#define BUFFER_SIZE 15
BYTE buffer[BUFFER_SIZE];
BYTE index = 0;
#int_rda
void serial_isr() {
buffer[index]=getch();
++index;
if(index== BUFFER_SIZE)
index = 0; // Buffer full !!
}
void clearbuf(BYTE buf[])
{
int j;
for( j =0; j < BUFFER_SIZE;j++)
{
buf[j] = '\0';
}
}
//----------------------------------------------------------------------------------
void CheckReceivedData() // function to check the Settings //
{
if(index!=0)
{ // if data is available
strcpy(mystring,buffer);
printf("data received : %s\n\r ",mystring); // print all array data
clearbuf(buffer);
index = 0;
}
}
void main()
{
enable_interrupts(int_rda);
enable_interrupts(global);
SPI_Initialize();
MCP23S17_Initialize();
printf("inits...\r\n");
MCP23S17_write(GPIOA, 5);
for(;;)
{
delay_ms(1000);
printf("waiting for data \n\r ");
CheckReceivedData();
delay_ms(1000);
output_b(SSPCON);// TO MAKE SURE SSPCON IS IN SPI MODE
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19562
|
|
Posted: Fri Mar 19, 2021 9:17 am |
|
|
You should include the chip setup lines. The #include, clock settings etc..
Without knowing the chip and how it is configured we can't help.
However your 'SPI_Initialise' is over-riding the #USE SPI setup. |
|
|
myloudharim
Joined: 13 Nov 2017 Posts: 10 Location: philly
|
|
Posted: Fri Mar 19, 2021 10:47 am |
|
|
Thanks for your time. Here are the fuses and device:
Code: |
#include <16F876.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9254 Location: Greensville,Ontario
|
|
Posted: Fri Mar 19, 2021 12:24 pm |
|
|
You need to add ERRORS to your rs232 options. |
|
|
myloudharim
Joined: 13 Nov 2017 Posts: 10 Location: philly
|
|
Posted: Fri Mar 19, 2021 8:47 pm |
|
|
here i modify these following two lines:
Code: |
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)
#use SPI (SPI1, FORCE_HW, MASTER, baud = 100000, DO = PIN_C5, DI = PIN_C4 , CLK = PIN_C3, LSB_FIRST, BITS = 8, Mode = 0)
|
and still not working. now uart and spi are not working together at the same time, i m thinking about dynamically disabling spi while uart is reading incoming chars and after mystring is full i ll disable uart and enable spi so that i can transfer content of mystring to mcp23s17 porta or portb...i ll be using #ifdef and #ifndef..... |
|
|
myloudharim
Joined: 13 Nov 2017 Posts: 10 Location: philly
|
UART and SPI Bridge issues |
Posted: Fri Mar 19, 2021 8:51 pm |
|
|
Code: |
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)
#use SPI (SPI1, FORCE_HW, MASTER, baud = 9600, DO = PIN_C5, DI = PIN_C4 , CLK = PIN_C3, LSB_FIRST, BITS = 8, Mode = 0)
|
still not working.
next i ll disable spi while uart is used and then do the opposit use spi and disable uart....we ll see |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19562
|
|
Posted: Sat Mar 20, 2021 1:22 am |
|
|
You have code here, that you have presumably copied from somewhere.
Now this code is doing all the SPI peripheral setup itself. It is not
designed for use with a #use spi statement.
You have some choices:
If your chip is the same as the chip for which this was written, then
use this code as it is without any #use spi.
If your chip is different, then you are going to have to go through the
data sheet for any differences in the SPI peripheral, and change the
values loaded to the registers to accommodate these changes.
Or you can simply use #use spi, and get rid of the original code.
All the initialisation code disappears, since #use spi does this. However
you are going to have to make the settings for this be for the correct
SPI mode.
Then for example SPI_Exchange8bit, is exactly the same as simply
using val=spi_xfer(sendval);
Beware that #use spi defaults to setting the fastest clock rate. You are
not specifying clock rate in your setup, and the hardware settings are
for using /64, so enormously slower than the clock rate #use spi
will be selecting.
Trying to mix #use spi with old code not designed for it, is not likely
to ever work. |
|
|
myloudharim
Joined: 13 Nov 2017 Posts: 10 Location: philly
|
CCS_16F876_UART_SPI_BRIDGE ISSUES SOLVED |
Posted: Thu Mar 25, 2021 4:58 pm |
|
|
Hello, hopefully everyone is okay, recently i had an issue with this little project UART SPI BRIDGE so my receive interruption stops each time i m using #SPI(xxx)...well no i have it working to day so hopefully will inspire eveyone that working on the same topic and big thanks for the people that want to give me a hand on that.....here is the code:
Code: |
#include "W:\CCS Projects\16F876_SPI_TEST.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <16F876.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//**********************************************************
#define DEVICE_ADDRESS_WRITE 0x40
#define DEVICE_ADDRESS_READ 0x41
#define IODIRA 0x00 //Data Direction Register for PORTA as output
#define IODIRB 0x01 //Data Direction Register for PORTB as input
#define GPIOA 0x12
#define GPIOB 0x13
#define OLATA 0x14
#define OLATB 0x15
#define IOCON 0x0A //OR 0x15
#define OUTPUT_DIR 0x00
#define INPUT_DIR 0xFF
#define CS PIN_A2
void CHIP_SELECT_SetLow(){
output_low(CS);
}
void CHIP_SELECT_SetHigh(){
output_high(CS);
}
void MCP23S17_write(int reg, int data) {
CHIP_SELECT_SetLow();
spi_write(DEVICE_ADDRESS_WRITE);
spi_write(reg);
delay_ms(1); //does not work without this delay
spi_write(data);
delay_ms(1); //does not work without this delay
CHIP_SELECT_SetHigh();
}
unsigned char MCP23S17_read(unsigned char address)
{
unsigned char received_data = 0;
CHIP_SELECT_SetLow();
spi_write(DEVICE_ADDRESS_READ);
spi_write(address);
delay_ms(1); //does not work without this delay
received_data = spi_read(0);
delay_ms(1);
CHIP_SELECT_SetHigh();
return received_data;
}
void MCP23S17_Initialize(void) {
MCP23S17_write(IOCON, 0x10);
MCP23S17_write(IODIRA, OUTPUT_DIR);
MCP23S17_write(IODIRB, INPUT_DIR);
delay_ms(10);
}
//--------------------------------------------Variables---------------------
int x_val;
int y_val;
unsigned char mystring[16];
#define BUFFER_SIZE 15
BYTE buffer[BUFFER_SIZE];
BYTE index = 0;
int x = 0;
#int_rda
void serial_isr() {
buffer[index]=getc();
++index;
if(index== BUFFER_SIZE)
index = 0; // Buffer full !!
}
void clearbuf(BYTE buf[])
{
int j;
for( j =0; j < BUFFER_SIZE;j++)
{
buf[j] = '\0';
}
}
void CheckReceivedData() // function to check the Settings //
{
if(index!=0)
{ // if data is available
strcopy(mystring,buffer);// for some reason strcpy does not work....and it worked already in the past
printf("data received : %s\n\r ",mystring); // print all array data
clearbuf(buffer);
index = 0;
x_val = atoi(mystring);
MCP23S17_write(GPIOA, x_val);
}
}
//--------------------------------------------------------------------------
void main()
{
enable_interrupts(global);
enable_interrupts(int_rda);
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_4);
delay_ms(500);
MCP23S17_Initialize();
delay_ms(500);
//MCP23S17_write(GPIOA, 0x05);
for(;;){
y_val = MCP23S17_read(GPIOB);
printf("-%u \r",y_val);
delay_ms(100);
CheckReceivedData();
delay_ms(100);
}
}
|
|
|
|
myloudharim
Joined: 13 Nov 2017 Posts: 10 Location: philly
|
|
Posted: Thu Mar 25, 2021 5:03 pm |
|
|
Thanks Ttemah for your answer,.....take care |
|
|
myloudharim
Joined: 13 Nov 2017 Posts: 10 Location: philly
|
|
Posted: Thu Mar 25, 2021 5:06 pm |
|
|
i did not wanna use software SPI ......#use SPI(xxx) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19562
|
|
Posted: Fri Mar 26, 2021 1:41 am |
|
|
Not using 'USE SPI, does not imply software SPI. The code you originally
posted, is setting up the SPI peripheral. |
|
|
|
|
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
|