This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GH6PM: spi communication

Part Number: TM4C123GH6PM

hi,

i am using the TM4C123GH6PM microcontroller. now i am working on the SPI communication.

i get the reference code from the application datasheet. i try to read the one energy meter ic (M90E32AS) registers.

this energy meter ic will communicate only through SPI.

i try to read some register values. i cannot get the proper default value of those registers. i am not sure my software is correct or not. 

can you please tell me my program is correct for reading those register or not ??

program:

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_ssi.h"
#include "inc/hw_types.h"
#include "driverlib/ssi.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"

#define NUM_SSI_DATA 8

const uint8_t pui8DataTx[NUM_SSI_DATA] = {0x88, 0xF8, 0xF8, 0x88, 0x01, 0x1F, 0x1F, 0x01};

uint32_t reg_addr_H = 0x00000010;
uint32_t reg_addr_L = 0x0000000D; // address value
uint32_t reg_data_H = 0x00000000;
uint32_t reg_data_L = 0x00000000;

uint32_t rec_addr_H = 0x00000000;
uint32_t rec_addr_L = 0x00000000;
uint32_t rec_data_H = 0x00000000;
uint32_t rec_data_L = 0x00000000;

// Bit-wise reverses a number.
//uint8_t Reverse(uint8_t ui8Number)
//{
// uint8_t ui8Index;
// uint8_t ui8ReversedNumber = 0;
// for(ui8Index=0; ui8Index<8; ui8Index++)
// {
// ui8ReversedNumber = ui8ReversedNumber << 1;
// ui8ReversedNumber |= ((1 << ui8Index) & ui8Number) >> ui8Index;
// }
//return ui8ReversedNumber;
//}


int main(void)
{
uint32_t ui32Index;
uint32_t ui32Data;
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
GPIOPinConfigure(GPIO_PA2_SSI0CLK);
GPIOPinConfigure(GPIO_PA3_SSI0FSS);
GPIOPinConfigure(GPIO_PA5_SSI0TX);
GPIOPinTypeSSI(GPIO_PORTA_BASE,GPIO_PIN_5|GPIO_PIN_3|GPIO_PIN_2);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // for mode pin in that energy meter ic
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2);
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_PIN_1);
GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2,GPIO_PIN_2);

SSIConfigSetExpClk(SSI0_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 10000, 16);
SSIEnable(SSI0_BASE);

while(1)
{

/* ****************************** master ******************************/

GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, 0);

SSIDataPutNonBlocking(SSI0_BASE, reg_addr_H);
SSIDataGet(SSI0_BASE, &(rec_addr_H));
SysCtlDelay(100);

SSIDataPutNonBlocking(SSI0_BASE, reg_addr_L);
SSIDataGet(SSI0_BASE, &(rec_addr_L));
SysCtlDelay(100);

SSIDataPutNonBlocking(SSI0_BASE, reg_data_H);
SSIDataGet(SSI0_BASE, &(rec_data_H));
SysCtlDelay(100);

SSIDataPutNonBlocking(SSI0_BASE, reg_data_L);
SSIDataGet(SSI0_BASE, &(rec_data_L));

SysCtlDelay(100);

GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);

}

}

i try to read that register : 0D . the default value is 13EC . but always i get FFFF only.

can you please verify my code tell me some solution for this issue.

regards

Arun Kumar.N

  • Hi Arun,
    I will suggest you start by referencing the SSI examples under <TivaWare_installation>\examples\peripherals\ssi.

    In your code you did not configure the RX pin from which you will read the external slave. Also I don't know why you are using GPIOPinWrite to set and clear the FSS pin. The FSS (or CS as in Freescale mode) will be automatically controlled by the SSI module during transmission. You don't need to manipulate this pin manually.
  • Charles Tsai said:
    Also I don't know why you are using GPIOPinWrite to set and clear the FSS pin.

    I would never recommend using the automatic chip select. GPIO is both easier and more reliable.

    Robert

  • As you well know - beware the use of: "Never, Always, Only etc."

    In the (admittedly rare) event that the MCU's SPI Format - "matches" the requirement of the SPI Slave - manual chip select (may) be avoided...
  • I wouldn't recommend it even in that event cb1.

    Robert
  • hi charles,

    can you please tell me how i want configure the RX pin from which slave i want to read the data.
    because, i mentioned like this.

    uint32_t reg_addr_H = 0x00000010; // for read from the slave
    uint32_t reg_addr_L = 0x0000000D; // from which address i want to read the data.

    is it correct way ???? if its not means can you tell me little bit clearly. if it's possible means can you please give me an example for how to read the data from the slave.


    regards
    Arun Kumar.N
  • Hi Arun,
    Please refer to the <TivaWare_installation>\examples\peripherals\ssi\spi_master.c for example. You will need to configure the RX pin similar to below.
    GPIOPinConfigure(GPIO_PA4_SSI0RX);
    GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 |GPIO_PIN_2);
  • No DMA for you!

    Respectfully,

    Dave

  • SourceTwo said:
    No DMA for you!

    ;)

    Chip select just becomes part of the DMA setup. Necessary for most modes in any case. If the extra overhead of setting/clearing a chip-select eliminates the DMA advantage there was never much purpose for the added complexity of DMA to begin with.

    Robert

  • hi sir,

    until i did not use the DMA. what ever the ic i am using (M90E32AS) in that datasheet they mentioned, for every operation read/write make that chip select pin low high. so that's why i make that pin as low and high.

    sir, now i am using that read pin also properly. i am using that what ever the code given i the example
    code(<TivaWare_installation>\examples\peripherals\ssi\spi_master.c )

    i want to read the register : 0D from that ic(M90E32AS) . for reading that register this functions are enough or i want to make any other changes
    in the program.


    regards
    Arun Kumar.N
  • Hi,

     No, you cannot use the spi_master.c as is for interfacing with the M90E32A5. The spi_master.c is just a loopback example transferring three data. I think you need to go through the M90E32A5 datasheet to understand the interface requirement. To read a register the MCU will need to generate 32 SCLK. The MCU SSI is only able to transmit 16 bit at a time. This means you will need to transfer 2x16-bit data. The first 16bit data will contain the register address that you want to read from. Make sure the first bit of the SDI is high according to the diagram to indicate it is a read operation. On your second 16-bit from the MCU, it can be just a dummy data. You will receive two 16-bit data at the end of the operation and the first 16-bit contains no useful information and you can ignore. It is the second 16-bit data that you receive contains the register value. Please reference the M90E32A5 datasheet.

  • Might the decision to, "Accept ANY sensor - then (painfully) divert & discover (tease out) & "only then" match unique peripheral requirements" - stray (too far) from this MCU forum's central purpose?

    Your effort in assisting here is to be "recognized" - yet it (necessarily) subtracts from (time/effort available for) more "key/critical" forum aid issues.     (i.e. such as providing more than the most "elementary" peripheral code examples...which have "remained w/out "deeper" support examples - for many (too many) years!)

    Supporting "each/every" sensor is - for sure - a losing proposition!      A superior path would be the creation of a, "General Solution Method" - which guides posters to the "essence of their (unique peripheral interface) issue" - while avoiding the dissipation of skilled vendor staff - forced AFAR from their proper, "MCU Sweet-Spot!"

    Many/most of such, "external peripheral issues" should be directed towards the "peripheral vendors" (not here) - should they not?       Instead - this forum (increasingly) serves as a "Dumping Ground" which is proven (right here - right now) as its most INEFFICIENT use...