Hi,
I have a clarification on how to use a ETPU pin as CS signal pin and access the device using macros.
Normaly a PCS0 - 5 signal will be there and its defined and read in the following way as in the code snippet.
now i need to know how it needs to be changed for using the ETPU pin as CS signal.
// Config pad as DSPI_C SOUT output
SIU.PCR[SOUT_PAD].R = ALT0 | OBE | SRC_max;
// Config pad as DSPI_D SIN input
SIU.PCR[SIN_PAD].R = ALT0 | IBE | SRC_max;
// Config pad as DSPI_D SCK output
SIU.PCR[SCK_PAD].R = ALT0 | OBE | SRC_max;
// Config pad as DSPI_C PCS0 output
SIU.PCR[PCS_PAD].R = ALT0 | OBE | SRC_max;
/*******************************************************************************
* Macros
*******************************************************************************/
#define ALLOW_TRANSFER DSPI_C.SR.R = DSPI_SR_EOQF
#define WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY while (!(DSPI_C.SR.B.RFDF)) {}
#define WAIT_UNTIL_TxFIFO_IS_FULL DSPI_C.SR.R = DSPI_SR_TFFF; \
while (!(DSPI_C.SR.B.TFFF)) {}
#define continuous_command_for_PUSH(x) DSPI_PUSHR_PCS0 | \
DSPI_PUSHR_CTAS(0) | \
DSPI_PUSHR_CONT | \
DSPI_PUSHR_TXDATA(x)
#define end_command_for_PUSH(x) DSPI_PUSHR_PCS0 | \
DSPI_PUSHR_CTAS(0) | \
(uint32_t) DSPI_PUSHR_EOQ | \
DSPI_PUSHR_TXDATA(x)
#define PUSH(n) DSPI_C.PUSHR.PUSHR.R = continuous_command_for_PUSH(n)
#define PUSH_ENQ(n) DSPI_C.PUSHR.PUSHR.R = end_command_for_PUSH(n)
#define POP(n) n = (uint8_t) (DSPI_C.POPR.R); \
DSPI_C.SR.R = DSPI_SR_RFDF
void DSPI_Init(void)
{
// DSPI is in master mode
// CS1 are inactive high
DSPI_C.MCR.R = DSPI_MCR_MSTR |
DSPI_MCR_PCSIS0 ;
DSPI_C.MODE.CTAR[0].R = DSPI_CTAR_FMSZ(0x0F) |
DSPI_CTAR_PCSSCK(4) |
DSPI_CTAR_DT(4) |
DSPI_CTAR_ASC(4) |
DSPI_CTAR_CSSCK(4) |
DSPI_CTAR_PASC_7CLK |
DSPI_CTAR_PDT_7CLK |
DSPI_CTAR_PBR_7CLK |
DSPI_CTAR_BR(0x8) ;
}
void spi_memory_ID_read(void)
{
uint8_t dummy_var;
uint8_t manufacturer_ID, device_ID;
//DSPI_B.MCR.R |= DSPI_MCR_CLR_RXF |
// DSPI_MCR_CLR_TXF; // clear FIFOs
ALLOW_TRANSFER; // if previous command has set EOQ
PUSH(RDID); // read data bytes command
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var); // discard one RxFIFO item
PUSH(0x00); // most-significant byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var); // discard one RxFIFO item
PUSH(0x01); // middle byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var); // discard one RxFIFO item
PUSH(0x02); // least-significant byte of address
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(dummy_var); // discard one RxFIFO item
PUSH(dummy_byte); // dummy byte for generating CLK to slave
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(manufacturer_ID); // read useful data
PUSH_ENQ(dummy_byte); // dummy byte for generating CLK to slave
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY;
POP(device_ID); // read useful data
}
This code involves PCS0 as CS signal and it works fine. Now if ETPU pin is needed to be used in place of CS how shall it be changed. For Example ETPU pin no 442.
Kindly help me through this.
Regards,
Vignesh
Hi,
I tried only as suggested by you as stated above in the code snippet by adding the pin initialization as GPIO.and also tried some other changes.
SIU.PCR[444].R = GPIO_FUNC |OBE|IBE;
DSPI_B.MODE.CTAR[0].R = DSPI_CTAR_FMSZ(0x07) |
DSPI_CTAR_PCSSCK(4) |
DSPI_CTAR_DT(4) |
DSPI_CTAR_ASC(4) |
DSPI_CTAR_CSSCK(4) |
DSPI_CTAR_PASC_7CLK |
DSPI_CTAR_PDT_7CLK |
DSPI_CTAR_PBR_7CLK |
DSPI_CTAR_BR(0x8);
can u tell whether the approach above is right or pl tell me if any changes required because it is not working.
if the above approach is right then I need to suspect the other things like slave device.
Regards,
Vignesh
Hi,
could you share a screenshot from oscilloscope to see all SPI signals?
Thanks,
Lukas
Hi,
I tried only as suggested by you as stated above in the code snippet by adding the pin initialization as GPIO.and also tried some other changes.
SIU.PCR[444].R = GPIO_FUNC |OBE|IBE;
DSPI_B.MODE.CTAR[0].R = DSPI_CTAR_FMSZ(0x07) |
DSPI_CTAR_PCSSCK(4) |
DSPI_CTAR_DT(4) |
DSPI_CTAR_ASC(4) |
DSPI_CTAR_CSSCK(4) |
DSPI_CTAR_PASC_7CLK |
DSPI_CTAR_PDT_7CLK |
DSPI_CTAR_PBR_7CLK |
DSPI_CTAR_BR(0x8);
can u tell whether the approach above is right or pl tell me if any changes required because it is not working.
if the above approach is right
#define ALLOW_TRANSFER_SPIB DSPI_B.SR.R = DSPI_SR_EOQF
#define WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY_SPI_B while (!(DSPI_B.SR.B.RFDF)) {}
#define PUSH_SPIB(x) SIU.GPDO[444].R |= 0; \
DSPI_B.PUSHR.PUSHR.R = DSPI_PUSHR_TXDATA(x)
#define PUSH_ENQ_SPIB(x) SIU.GPDO[444].R |= 1; \
DSPI_B.PUSHR.PUSHR.R = DSPI_PUSHR_TXDATA(x)
#define POP_SPIB(n) n = (uint8_t) (DSPI_B.POPR.R); \
DSPI_B.SR.R = DSPI_SR_RFDF
void DSPI_B_Init()
{
DSPI_B.MCR.R = DSPI_MCR_MSTR |
DSPI_MCR_PCSIS0 ;
DSPI_B.MODE.CTAR[0].R = DSPI_CTAR_FMSZ(0x7) |
DSPI_CTAR_PCSSCK(4) |
DSPI_CTAR_DT(4) |
DSPI_CTAR_ASC(4) |
DSPI_CTAR_CSSCK(4) |
DSPI_CTAR_PASC_7CLK |
DSPI_CTAR_PDT_7CLK |
DSPI_CTAR_PBR_7CLK |
DSPI_CTAR_BR(0x8);
}
uint8_t spi_ID_read()
{
uint8_t dummy_var;
uint8_t device_ID;
(void)(dummy_var);
ALLOW_TRANSFER_SPIB;
PUSH_SPIB(0x80); // read device ID register command
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY_SPI_B;
POP_SPIB(dummy_var);
PUSH_ENQ_SPIB(dummy_byte); // dummy bytes for generating CLK to slave
WAIT_UNTIL_RxFIFO_IS_NOT_EMPTY_SPI_B;
POP_SPIB(device_ID); // read data
return device_ID;
}
This is what I modified but its not working pl guide me whether anything wrong / to be modified.
Regards,
Vignesh
Hi,
there's no difference at all. You can use the same initialization - only add initialization of selected GPIO pin.
Depending on your slave device, it may be necessary to add small delay between assertion of chip select (GPIO pin) and writing to PUSH register. You can check the real timing using oscilloscope and then compare it with datasheet of your slave device.
Unfortunately I do not have sample code but this should be quite easy.
Regards,
Lukas
hi,
this for read data right . could u pl tell how to initialize for it does it remains same.
// Config pad as DSPI_C SOUT output
SIU.PCR[SOUT_PAD].R = ALT0 | OBE | SRC_max;
// Config pad as DSPI_D SIN input
SIU.PCR[SIN_PAD].R = ALT0 | IBE | SRC_max;
// Config pad as DSPI_D SCK output
SIU.PCR[SCK_PAD].R = ALT0 | OBE | SRC_max;
// Config pad as DSPI_C PCS0 output
SIU.PCR[442].R = ALT0 | OBE;
and what about init with CTAR is it not required?
I mean something like this
void DSPI_Init(void)
{
// DSPI is in master mode
// CS1 are inactive high
DSPI_C.MCR.R = DSPI_MCR_MSTR |
DSPI_MCR_PCSIS0 ;
DSPI_C.MODE.CTAR[0].R = DSPI_CTAR_FMSZ(0x0F) |
DSPI_CTAR_PCSSCK(4) |
DSPI_CTAR_DT(4) |
DSPI_CTAR_ASC(4) |
DSPI_CTAR_CSSCK(4) |
DSPI_CTAR_PASC_7CLK |
DSPI_CTAR_PDT_7CLK |
DSPI_CTAR_PBR_7CLK |
DSPI_CTAR_BR(0x8) ;
}
Can I have an example reference somewhere so that I can relate it?
Thanks in advance,
Vignesh.v
Hi,
you can just configure selected pin as output and then follow this pseudo code:
Assert_CS(); //write the output to '0'
PUSHR = data; //send data via SPI
while(data_not_sent); //wait until the data are transferred
Deassert_CS(); //write the output to '1'
You can use any IO pin for this.
Regards,
Lukas
hi,
this for read data right . could u pl tell how to initialize for it does it remains same.
// Config pad as DSPI_C SOUT output
SIU.PCR[SOUT_PAD].R = ALT0 | OBE | SRC_max;
// Config pad as DSPI_D SIN input
SIU.PCR[SIN_PAD].R = ALT0 | IBE | SRC_max;
// Config pad as DSPI_D SCK output
SIU.PCR[SCK_PAD].R = ALT0 | OBE | SRC_max;
// Config pad as DSPI_C PCS0 output
SIU.PCR[442].R = ALT0 | OBE;
and what about init with CTAR is it not required?
I mean something like this
void DSPI_Init(void)
{
// DSPI is in master mode
// CS1 are inactive high
DSPI_C.MCR.R = DSPI_MCR_MSTR |
DSPI_MCR_PCSIS0 ;
DSPI_C.MODE.CTAR[0].R = DSPI_CTAR_FMSZ(0x0F) |
DSPI_CTAR_PCSSCK(4) |
DSPI_CTAR_DT(4) |
DSPI_CTAR_ASC(4) |
DSPI_CTAR_CSSCK(4) |
DSPI_CTAR_PASC_7CLK |
DSPI_CTAR_PDT_7CLK |
DSPI_CTAR_PBR_7CLK |
DSPI_CTAR_BR(0x8) ;
}
regards,
Vignesh.v