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.

RM48L952ZWT HalCoGen (4.03.00) autogenerated spi.c (spiReceiveData)

Other Parts Discussed in Thread: HALCOGEN, RM48L952

Hello we are using the RM48L952ZWT HalCoGen (4.03.00) autogenerated spi.c code. For the

uint32 spiReceiveData(spiBASE_t *spi, spiDAT1_t *dataconfig_t, uint32 blocksize, uint16 * destbuff)

1. Do you have an example of using this function?

2. is blocksize = number of bytes?

3. specifically the 2nd argument spiDAT1_t *dataconfig_t? How should this be set when we want to use this function?  We are writing to a wireless slave over SPI, and we want to be able to write i.e.,

.....

//pull D3 pin low

bsp_SPI_GPIO_OFF(TERMINAL_D3_SPI2_GIO);

//delay 250usecs

_pmuSetCountEvent_(pmuCOUNTER0, PMU_CYCLE_COUNT);

BSP_OS_TimeDlyPMU(250);

//pull D3 pin high

bsp_SPI_GPIO_ON(TERMINAL_D3_SPI2_GIO);

//delay 2msecs

BSP_OS_TimeDlyMs(2);

/* do a soft reset */

spiTransmitData(spiREG3, pTest, 1, pTransmitData);

 

transmitData = INIT_SOFTRST;

spiTransmitData(spiREG3, pTest, 1, pTransmitData);

....

then read back a status of the processor i.e.,

 

do

{

transmitData = READ_SOFTRST;

spiTransmitData(spiREG3, pTest, 1, pTransmitData);

spiReceiveData (spiREG3,??,1,destbuff);

i = * destbuff;

}

while((i&0x07) != (CPU_INT08U)0x00);

 

datasheet for slave is here: 3757.39776C.pdf

 

 

 

Thank you.

  • Tammy,

    I took a look at the datasheet you attached. You cannot use halcogen function for what you need. MRF24J40 requires 8 bit or 12 bit SPI transfer. You can create your customized function by modifying the halcogen function. Please pay attention that MRF24J40 requires of two word together: address and data. The CS line needs to be low during the transfer.

    Thanks and regards,

    Zhaohong
  • Hi Zhaohong. Thank you. You wrote "Please pay attention that MRF24J40 requires of two word together". Yes for example the address = 0x55 and value 0x07. Can you explain what the piDAT1_t *dataconfig_t is in the spiReceiveData api? Can you please give a practical example of what you mean of changing function to support 8-bit or 16 bit transfers?. as long as we control to only put a byte in srcbuf and we pass a "1" in blocksize, would that work ok? i.e., HalCoGen generates below. What is this HalCoGen supporting only? Can you give an example how to change this to what you describe?

    /** @fn uint32 spiTransmitData(spiBASE_t *spi, spiDAT1_t *dataconfig_t, uint32 blocksize, uint16 * srcbuff)
    * @brief Transmits Data using polling method
    * @param[in] spi - Spi module base address
    * @param[in] dataconfig_t - Spi DAT1 register configuration
    * @param[in] blocksize - number of data
    * @param[in] srcbuff - Pointer to the source data ( 16 bit).
    *
    * @return flag register value.
    *
    * This function transmits blocksize number of data from source buffer using polling method.
    */
    /* SourceId : SPI_SourceId_005 */
    /* DesignId : SPI_DesignId_005 */
    /* Requirements : HL_SR131 */
    uint32 spiTransmitData(spiBASE_t *spi, spiDAT1_t *dataconfig_t, uint32 blocksize, uint16 * srcbuff)
    {
    volatile uint32 SpiBuf;
    uint16 Tx_Data;
    uint32 Chip_Select_Hold = (dataconfig_t->CS_HOLD) ? 0x10000000U : 0U;
    uint32 WDelay = (dataconfig_t->WDEL) ? 0x04000000U : 0U;
    SPIDATAFMT_t DataFormat = dataconfig_t->DFSEL;
    uint8 ChipSelect = dataconfig_t->CSNR;

    /* USER CODE BEGIN (10) */
    if(g_printFunction && !spiTransmitDataUsed)
    {
    spiTransmitDataUsed = 1;
    strcat(g_SPI_buffer, __FUNCTION__);
    strcat(g_SPI_buffer, ",\r\n");
    }
    /* USER CODE END */
    while(blocksize != 0U)
    {
    if((spi->FLG & 0x000000FFU) !=0U)
    {
    break;
    }

    if(blocksize == 1U)
    {
    Chip_Select_Hold = 0U;
    }
    /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are only allowed in this driver" */
    Tx_Data = *srcbuff;

    spi->DAT1 = ((uint32)DataFormat << 24U) |
    ((uint32)ChipSelect << 16U) |
    (WDelay) |
    (Chip_Select_Hold) |
    (uint32)Tx_Data;
    /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */
    srcbuff++;
    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
    while((spi->FLG & 0x00000100U) != 0x00000100U)
    {
    } /* Wait */
    SpiBuf = spi->BUF;

    blocksize--;
    }

  • Hi Zhaohong, Forgive me I forgot to add. I have tried to pull the CS low (spiREG3->PC3 = spiREG3->PC3 & 0xFFFFFFFE;), but it stays high (there is a pull up resistor). But shouldn't I be able to toggle it just from writing to the bit 0 of the spiREG3->PC3 a 0 (low) and 1 (high)?
  • If you want to manually set it low, you need to do the following.

    (1) Configure the pin ad GPIO output.
    (2) Set the pin low.

    You cannot set it low when the pin is configured as a SPI pin.

    Thanks and regards,

    Zhaohong
  • Hi Zhaohong. Thank you. To use the SPI, do I have to change SPI CS pin to GIO and then then set it low, and then set it back to SPI pin? Or can it be set as a GIO (and I can leave it like this by default), but used as CS for the SPI? i.e.,

    spiREG3->PC0 = spiREG3->PC0 & 0xFFFFFFFE;

    spiREG3->PC3 = spiREG3->PC3 & 0xFFFFFFFE;

    spiREG3->PC0 = spiREG3->PC0 | 0x00000001;

  • You need to write to SPIPC1 to make it as output.

    Thanks and regards,

    Zhaohong
  • Hi Zhaohong. Thank you. For the TI HalCoGen function in spi.c called

    uint32 spiReceiveData(spiBASE_t *spi, spiDAT1_t *dataconfig_t, uint32 blocksize, uint16 * destbuff) and spiTransmitData((spiBASE_t *spi, spiDAT1_t *dataconfig_t,...)

    1. Do you have an example of using these functions with the 2nd argument spiDAT1_t *dataconfig_t properly configured?

    2. What is this argument spiDAT1_t *dataconfig_t? How should we set the different fields when we want to use this function?
  • Tammy,


    Check the following post:

    void main(void)
    {

    uint16 TX_Data_Master[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 };

    spiDAT1_t dataconfig1_t;


        dataconfig1_t.CS_HOLD = FALSE;                                // Specify if CS has to be held low for the full transmission.
        dataconfig1_t.WDEL    = TRUE;
        dataconfig1_t.DFSEL   = SPI_FMT_0;                            // Specify which data format to use. They are defined in Halcogen
        dataconfig1_t.CSNR    = 0xFE;

        /* Initialize SPI Module Based on GUI configuration
         * SPI1 - Master ( SIMO, SOMI, CLK, CS0 )
         * */
        spiInit();                                                                       // Initialize all spi as defined in Halcogen.

        /* Initiate SPI1 Transmit  through Polling Mode*/
        spiTransmitData(spiREG1, &dataconfig1_t, 16, TX_Data_Master);    // Send TX_Data_Master using SPI1
                                                                                                                    // using the attribute defined in dataconfig1_t
                                                                                                                    // Send 16 Data (size of data is define in Format0 in this example

        while(1);
    /* USER CODE END */ }

    }

    If you want to use a data size of 8 bits, the api is still expecting for argument 3 (TX_Data_Master) a 16bit pointer.
    This is not an issue, just not optimized. If you plan to use the 12bit communication mode, than define is Halcogen the character length to 12.

    Please let me know if this is helpful.

  • Hi Jean-Marc, Thank you it is helpful.

    Since we need to pull the CS low for this slave part, so dataconfig1_t.CS_HOLD = TRUE; But do we also need to do the:

    piREG3->PC0 = spiREG3->PC0 & 0xFFFFFFFE;
    spiREG3->PC1 = spiREG3->PC1 | 0x00000001;
    spiREG3->PC3 = spiREG3->PC3 & 0xFFFFFFFE;

    without the above 3 lines even with setting CS_HOLD, the pin is not pulled low.

    In HalCoGenSPI Data Format section. Where do we get the information on how to configure HalCoGen for this part? It is not obvious fron the datasheet when to set wait for enable, clock phase, baudrate, etc. Thank you again.
  • Hi Jean-Marc. I also just got updated from vendor that the SPI needs to be running at 10MHz or less. Does that make sense to you? By default in HalCoGen it is VCLK1 is 100MHz. Can we adjust something else to slow this down for this part that will not impact the other part we have on this same SPI? Below from vendor:

    Microchip Engineering Support has added comments to support Ticket 291607.

    Comments:

    Tammy,


    Below is a snippet of information from MRF24J40Init(void). Please note, the BoardInit() needs to be executed, to enable the the SPI port as 10 MHz or less w/ the required settings, before executing MRF24J40Init(void).

    Here is datasheet; 7140.39776C.pdf

  • Tammy,


    The SPI baudrate is programmable. Yes the 100Mhz is the clock used by almost all peripheral modules, but inside each SPI there is a baudrate register that is there to prescale the 100MHz.

    Here is a screeshoot from Halcogen MIBSPI1 Data Format.

    As you can see, the VCLK1 is 100Mhz, the requested baudrate is 500Khz and the actual baudrate is 500Khz.
    To achieve this result we have:

    100Mhz/ 199 + 1 = 500khz.

    The 199 is the value to write in the baudrate register. The formula as visible in the TRM is:

    VCLK/ baudrate prescaler value + 1 = SPI Baudrate.

    Again, each SPI instances (MIBSPI or SPI) have  their own prescaler.

  • Hi Jean-Marc. Thank you. So if the vendor wants it to be 10MHz then we set HalCoGen baudrate = 10000 (then Prescale changes to 9 in HalCoGen) so 100/10 = 10 MHz?

    What about the other fields such as Wdelay, Clock Polarity, Clock Phase, Parity Enable, etc. How do we know if those are needed?

  • Tammy,


    I never heard about MRF24J40 before your post.
    But after reading the specification that you posted, and by reading it (especially chapter 2.13 Serial Peripheral Interface) I can say:

    1] Incoming data on SDI of MRF24J40 are sample on rising edge of SPICLK. so Phase as to be 1 and Polarity 0.
    2] MRF24J40 supports 2 mode: Short Address Read/Write or Long Address Read/Write.
        In short mode, SPI Character length has to be programmed to 8 bits.
        In long mode, SPI Character length has to be programmed to 12 bits.
    3] MRF24J40 protocol does not support parity.
    4] If SPI is used in 4 pins mode (SOMI, SIMO, CLK, CS) than CS Hold has to be used. This will keep CS active low for the full transmission of multiple data as required by MRF24J40. "The CS pin must be held low while communicating with the MRF24J40. Figure 2-4 shows timing for a write operation."
    5} There is no need to enable WDelay and the default value for C2TDELAY and T2CDELAY should be enough.

    Please let me know if this is helpful.

  • Hi Jean-Marc. Thank you.

    1. I configured 2 data formats, 1 for 8 bit for short and one (SPI_FMT_1) for 12 bit for the address long transfers(SPI_FMT2) In the dataconfig1_t fields you gave example above. If this device is on CS0 on RM48L952 board, what should the CSNR be set to? You had it set to 0xFE in your example, btu there was no comment in sample code and It was not clear in the datasheet. (dataconfig1_t.CSNR = 0xFE;)

    2. For pulling the CS low, in addition to setting CS_HOLD = true, do we still have to change the PC0,PC1, and OC3 registers as Zhoahong described above? or should only setting CS_HOLD = true should be enough?

    i.e.,

    spiREG3->PC0 = spiREG3->PC0 & 0xFFFFFFFE;

    spiREG3->PC1 = spiREG3->PC1 | 0x00000001;

     spiREG3->PC3 = spiREG3->PC3 & 0xFFFFFFFE;

    dataconfig1_t.CS_HOLD = TRUE; // Specify if CS has to be held low for the full transmission.

    dataconfig1_t.WDEL = FALSE;

    dataconfig1_t.DFSEL = SPI_FMT_1; // Specify which data format to use. They are defined in Halcogen

    dataconfig1_t.CSNR = 0xFE;

    3. For the long writes, is it only the address that should be transmitted with the 12 bit format and if data transferred switch back to setting the DFSEL to the otherformat? Or if there is both address and data to transmit we can send both in the 12 bit format?

    i.e.,

    void transmitWirelessLongAddress(uint16 transmitAddress, uint16 transmitData)

    {

    uint16 *pTransmitData;

    spiDAT1_t dataconfig1_t;

    spiDAT1_t* pDataConfig1_t;

    uint16 transmitAddress1,transmitAddress2;

    dataconfig1_t.CS_HOLD = TRUE; // Specify if CS has to be held low for the full transmission.

    dataconfig1_t.WDEL = FALSE;

    dataconfig1_t.DFSEL = SPI_FMT_2; // Specify which data format to use. They are defined in Halcogen

    dataconfig1_t.CSNR = 0xFE;

    pDataConfig1_t = &dataconfig1_t;

    pTransmitData = &transmitAddress;

    spiTransmitData(spiREG3, pDataConfig1_t, 1, pTransmitData);

    dataconfig1_t.DFSEL = SPI_FMT_1; // Specify which data format to use. They are defined in Halcogen

    pTransmitData = &transmitData;

    spiTransmitData(spiREG3, pDataConfig1_t, 1, pTransmitData);

    }

    or

    void transmitWirelessLongAddress(uint16 transmitAddress, uint16 transmitData)

    {

    uint16 *pTransmitData;

    spiDAT1_t dataconfig1_t;

    spiDAT1_t* pDataConfig1_t;

    uint16 transmitAddress1,transmitAddress2;

    dataconfig1_t.CS_HOLD = TRUE; // Specify if CS has to be held low for the full transmission.

    dataconfig1_t.WDEL = FALSE;

    dataconfig1_t.DFSEL = SPI_FMT_2; // Specify which data format to use. They are defined in Halcogen

    dataconfig1_t.CSNR = 0xFE;

    pDataConfig1_t = &dataconfig1_t;

    pTransmitData = &transmitAddress;

    spiTransmitData(spiREG3, pDataConfig1_t, 1, pTransmitData);

    pTransmitData = &transmitData;

    spiTransmitData(spiREG3, pDataConfig1_t, 1, pTransmitData);

    }

    and short is

    void transmitWirelessShortAddress(uint16 transmitAddress, uint16 transmitData)

    {

    uint16 *pTransmitData;

    spiDAT1_t dataconfig1_t;

    spiDAT1_t* pDataConfig1_t;

    dataconfig1_t.CS_HOLD = TRUE; // Specify if CS has to be held low for the full transmission.

    dataconfig1_t.WDEL = FALSE;

    dataconfig1_t.DFSEL = SPI_FMT_1; // Specify which data format to use. They are defined in Halcogen

    dataconfig1_t.CSNR = 0xFE;

    pDataConfig1_t = &dataconfig1_t;

    pTransmitData = &transmitAddress;

    spiTransmitData(spiREG3, pDataConfig1_t, 1, pTransmitData);

    pTransmitData = &transmitData;

    spiTransmitData(spiREG3, pDataConfig1_t, 1, pTransmitData);

    }

  • Tammy,

    1] CNSR = 0xFE means CS0 will be activate each time a transfer is started by writing in the SPIDAT1 register.

    Here is an extract from Halcogen spiTransmitData function.

            spi->DAT1 =  ((uint32)DataFormat << 24U) |
                                  ((uint32)ChipSelect << 16U) |
                                  (WDelay)           |
                                  (Chip_Select_Hold) |
                                  (uint32)Tx_Data;


    spi->DAT1 is a 32 bit register. Here are the different field in this register.

    Each time this function is called, for each data to be transmitted all these field are used.
    During a given transmission using spiTransmitData the CS, DATA Format and other parameter will be the same. Only the Data to be transmitted will change.

    2] If SPICSx in your case SPICS0 is defined as a functional pin, than there is no need to control the CS by hand. SPI will automatically assert CS low for you.
    As I said before, if more than 1 data has to be transmitted, and CS_HOLD is true, than SPI will assert CS low before the first data, and will keep it low for all other data. When the last data has been transmitted than CS will be released High.

    3] Here again the solution is in the datasheet.

    For short Address mode, both Address and Data are 8 bits. Address starts with a 0, 6 address bit and a 1 make 8. For Data, 8bits D7 to D0.

    Now for Long Address mode, both address and data are 12 bits. Address will always start with a 1 than 10 bits of address and another 1 make 12.
    For the data, the valid bits are D7 to D0. D11 to D8 are dummy bit or don't care.

    NOTE.

    The spiTransmitData only send data to a slave. The incoming data is not used and not read by the function. This function can be used to write to the Slave device.

  • Hi Jean marc. Thank you.  Do you think the RM48 SPI module can be slowed down enough for the wireless slave to process the data transmitted (using the baud rate as you originally described)? After transmission, in order to receive from the slave device -- does CS0 have to go back to HIGH to receive data over CS0 from wirless slave processor?

     We have been sending data, and then trying to read back a response using both spiReceive and the spiTransmitAndReceiveData in the HalCoGen driver. We have hooked up a scope also -- we can see the data being transmitted, but no matter how we change the baud rate to slow down the transmission the wireless slave does not respond.  Can you show an example of using the spiReceive? We thought we have to do an spiTransmit with the address on the wireless that we want to read, then call spiReceive to actual get the data. Thank you again.

  • Hi Jean-Marc. I wanted to clarify.

    When doing the spiTransmit, of the 2 byes for Address and Data is it better to send out each byte in a separate function call or send both bytes in a data structure in the same call (with block size 2) . Right now we do each byte transmission independently, rather then grouping the address and data together to 1 spiTransmit function call.

     We also needed a software example of how to use the HalCoGen generated spiReceive software function (our deadline is Friday to get this running). We can see data going out on masterOut on the scope with the SpiTransmit, bit nothing coming over masterIn and we wanted to double check if we are using the spiRceive function properly. Or if the problem is in how we are writing to the wireless (the spiTransmit question above), and if that was why when we tried to read back the same address we get no response over SPI at all. No response over SPI at all.

    Could the version of the spi functions we are using have a problem?  Thank you again

    i.e:

    ...

    uint16 *pTransmitData;

    spiDAT1_t dataconfig1_t;

    spiDAT1_t* pDataConfig1_t;

    ...

    transmitAddress = READ_SOFTRST;

    dataconfig1_t.CS_HOLD = TRUE; // Specify if CS has to be held low for the full transmission.

    dataconfig1_t.WDEL = FALSE;

    dataconfig1_t.DFSEL = SPI_FMT_1; // Specify which data format to use. They are defined in Halcogen

    dataconfig1_t.CSNR = 0xFE;

    pDataConfig1_t = &dataconfig1_t;

    pTransmitData = &transmitAddress;

    spiTransmitData(spiREG3, pDataConfig1_t, 1, pTransmitData);

    spiReceiveData(spiREG3, pDataConfig1_t, 1,pDestBuff);

  • Tammy,


    The timing diagram part of the MRF24J40 are very clear.

    All communication starts with:

    Assert CS low;
    Start shifting the data to slave. If first bit is 0 than we are in SHORT address mode else we are in LONG address mode, the next 6 bit are the address, the following bit (8th one) is:
         0 Write
         1 Read
    End of first data (if short mode)
    Start next shift (WITH CS STILL LOW)
    If a write is performed, the SPI will now send the data to the slave, the slave send back a dummy data.
    If a read is performed, the SPI will now send a dummy data, the slave is sending the requested data.
    The communication is done, CS can be de-asserted (HIGH)

    So if you want to Write to your slave, you have to use the following SPI function:
    spiTransmitData(spiREG3, pDataConfig1_t, 2, Tbuff);

    Tbuff[]={0x55,0xab};    // 0x2A is the address of the soft reset register, this is a short address.
                                        // The address has to be shifted by 1 bit to the left and bit 0 has to be 1 for read, 0 for write.
                                        // So 0x2A <<1 = 0x54.  0x54 + 1 (for write) = 0x55
                                       // Than the data 0xab is send to the destination register to be written. 

    Now if you want to Read to this register:

    Rbuff[]={0x00,0x00);   //
    Tbuff[]={0x54,0x00};    // 0x2A is the address of the soft reset register, this is a short address.
                                        // The address has to be shifted by 1 bit to the left and bit 0 has to be 1 for read, 0 for write.
                                        // So 0x2A <<1 = 0x54.  0x54 + 0 (for read) = 0x54
                                        // 0x00 is the dummy data you have to send in order to read back the content of the addressed register.

    spiTransmitAndReceiveData(spiREG3, pDataConfig1_t, 2, Tbuff, Rbuff);

    // At the end of this transfer of 2 data, Rbuff[1] is the value of the requested register, in this case Soft Reset.

    Use the same concept for long address, with a different format (12 bits instead of 8 bits)

    For the baudrate question, if your VCLK1=100Mhz and you want the SPICLK to be 10Mbaud, you will have to divide by 10. (9+1)
    In Halcogen SPIx Data Format, you have to enter the baudrate in the top left box (Baudrate (Khz)) Base on the value of VCLK1 Halcogen will display the Prescaler value. This is an integer number. Also Halcogen will display the Actual Baudrate.

    With a VCLK1 = 100Mhz, the slowest baudrate achievable is: 100/(255+1) = 390.625 Khz.

    This all I can do, I don't have a slave to make a real test.

    By the way, are you using a demo board from Microchip?

  • Tammy,

    I've found this example on the web:

    Here they are using a different approach because the SPI used in this example is only capable of transferring 8 bits.
    For short address, the first 8 bits is the address, the second is the data.
    For long address, a total of 24 bits have to be send. 12 for the address, and 12 for the data.
    Because their SPI is only 8 bits, they send 3 x 8bits = 24bits.

    For a long write they are doing something lile:

         CS = 0;

        spiPut((((UINT8)(address>>3))&0x7F)|0x80);
        spiPut((((UINT8)(address<<5))&0xE0)|0x10);
        spiPut(value);

        CS =1;

    The reason they have the CS=0 and CS=1 is because their SPI does not control the CS line automatically.

    What you can reuse from this example is the MRF24J40.h. This defines a lot of stuff, including all Registers translated address for read and write.

    Example:

    #define READ_SOFTRST (0x54)                           // Specification real address is 0x2A
    #define WRITE_SOFTRST (0x55)                          // Specification real address is 0x2A

    Also you will find the code they are using to initialize this slave. This could be handy.

    Please let me know if this is helpful

  • Hi Jean-Marc. Thank you. Yes we had the sample code. It was more how to apply to the HalCoGen API for your SPI. We changed to use the spiTransmitAndReceiveData (you wrote we had to transmit 2 bytes) -- for our reads to transmit the address of what we want to read and 1 dummy byte (0x00). For the writes we use the spiTransmit of two bytes (the address and data)., so i.e.:

    spiTransmitAndReceiveData(spiREG3, pDataConfig1_t, 2, pTransmitData ([0] = 0x54 and [1] = 0x00 as in your example),pReceiveData);

    spiTransmitData(spiREG3, pDataConfig1_t, 2, pTransmitData); ([0] = 0x55 and [1] = 0x07 )

    When we singlestep with a debugger (this it is slower then between the transfer of each byte, etc.) the code in the spi functions above, we can transmit and receive Ok. But when we do not use the debugger it fails (it is running fatser of course). Can we configure something in HalCoGen SPI tab to slow down the transfers between the bytes? Or do we need to modify the HalCoGen functions manually to add delays?  Thank you again.

     

  • Tammy,

    What are the reference of the board you are using for MRF24J40? Is it a Micrichip development board or a custom board?
    Any progress?
  • Hi Jean-Marc,

    Thank you for checking in. I didn't want to bother you too much until we had more information  I have uploaded the datasheet for the microchip board version here: 4130.70005173A.pdf

    One of our hardware engineers is looking today to wire up something we can may be mail you with another Hercules board and this wireless part with our project so you can see what is happening.  

    I have the short (8-bit) address read/writes look like their working, but not the long address (12 bit) still has problems. also, when I removed the gio toggling of the pin that Zhaohong told me to do to pull the CS0 low, and went back to SPI3CS0 being an SPI pin with the writing to the datastructure -- it does not work to pull the CS0 low even with the values you provided. So there is something else missing. I have temporarily put the manual CS0 toggling back in from  Zhaohong  until you can get the hardware to see if it s a configuration issue or something with HalCoGen autogenerated code that needs updating (we are using HalCoGen 4.03.00).  What do you think? Or have you heard of any issues where we should modify any of the HalCoGen functions so the auto pulldown of the CS is working? DO you have any idea why the 12 bit (long address) would not work? I thought it would be the same code, except just the different data format for 12 bit rather then 8 bit?

    Take Care,

    Tammy

  • Tammy,

    I've build a basic Halcogen code for RM48 with 0nly SPI3 enable.

    The CPU Clock is 200Mhz, VCLK1 is 100Mhz and SPI3CLK is 5Mhz.

    In the ZIP file you have the Halcogen configuration as well as the Source and Include directory.

    In Sys_Main.c the spiInit() is called and I'm only using the spiTransmitData

    On the first call, I'm doing:

    spiTransmitData(spiREG3, &dataconfig1_t, 2, TX_Master);

    On the second call, I'm doing:

    spiTransmitData(spiREG3, &dataconfig2_t, 2, TX_Master);

    dataconfig1_t is configured to use Format0 as 8bit, with CS_HOLD = FALSE.

    dataconfig1_t is configured to use Format1 as 12bit, with CS_HOLD = TRUE.

    SPI3CLK, SPI3SOMI, SPI3SIMO, SPI3nCS0 are defined as functional pins.

    Here is the resulting waveform.

    As you can see, the SPI3nCS is asserted low automatically at the beginning of the first data.
    In case of 8 bit (Format0) I've specified CS_HOLD=FALSE so the SPI3nCS0 is de-asserted after the first 8 bits.
    It's not the case the second part, when Format1 is use (12 bits) and CS_HOLD=TRUE.

    This will work the exact same way with all other SPI API like spiTransmitAndReceiveData

    Also, you can see that in between the first and second data, there is a delay. This is the code executed in the API to load the next data, calculate if blocksize is reached.... So there is no need to play with WDelay.

    All other delay (CS to CLK and CLK to CS are default 0 in this example)

    2045.RM48_MRF24J40.zip

  • Hi Jean-Marc.  Thank you.

    1. For the data format issue, when we talked with Microchip the engineer said that their wireless could not support the 12-bit transfer that the RM48 (it was too advanced for the wireless processor he said, does that sound correct to you?). So we had to do a 3 byte transmit with 8-bit data format and then it worked (2 address and 1 data) as follows:

    void transmitWirelessLongAddress(uint16 transmitAddress, uint16 transmitData)
    {
     uint16 *pTransmitData;
     uint16 transmitAllData[3];
     spiDAT1_t* pDataConfig1_t;
     spiDAT1_t dataconfig1_t;

     dataconfig1_t.CS_HOLD = TRUE;                                // Specify if CS has to be held low for the full transmission.
     dataconfig1_t.WDEL    = FALSE;
     dataconfig1_t.DFSEL   = SPI_FMT_1;                            // Specify which data format to use. They are defined in Halcogen
     dataconfig1_t.CSNR    = 0xFE;

     pDataConfig1_t = &dataconfig1_t;

        transmitAllData[0] = ((((transmitAddress>>3))&0b01111111)|0x80);
        transmitAllData[1] = ((((transmitAddress<<5))&0b11100000)|0x10);
        transmitAllData[2] = transmitData;

        pTransmitData = &transmitAllData[0];

        enableSPI_CS0();
        spiTransmitData(spiREG3, pDataConfig1_t, 3, pTransmitData);
        disableSPI_CS0();
    }

    but we can live with this.

    2. The bigger problem is the Chip Select problem, we have tried a second board (with the scope connected to CS0) but the CS is not pulled down.  Here is what HalCoGen autogenerated here for spi.c/spi.h:

    Our transmit code is set with the data structure set up the way you suggested as above.

     dataconfig1_t.CS_HOLD = TRUE;                                // Specify if CS has to be held low for the full transmission.
     dataconfig1_t.WDEL    = FALSE;
     dataconfig1_t.DFSEL   = SPI_FMT_1;                            // Specify which data format to use. They are defined in Halcogen
     dataconfig1_t.CSNR    = 0xFE;

    Is there anything else that could keep this auto chipselect feature from working properly with the above dataconfig1_t configuration, where manually changing the registers does work?

    Thank you again Here is the HalCoGen 4.03.00 autogenerated library we are using:.1488.HalCoGen.zip

  • Hi Jean-Marc.  Thank you.

    1. For the data format issue, when we talked with Microchip the engineer said that their wireless could not support the 12-bit transfer that the RM48 (it was too advanced for the wireless processor he said, does that sound correct to you?). So we had to do a 3 byte transmit with 8-bit data format and then it worked (2 address and 1 data) as follows:

    void transmitWirelessLongAddress(uint16 transmitAddress, uint16 transmitData)

    {

    uint16 *pTransmitData;

    uint16 transmitAllData[3];

    spiDAT1_t* pDataConfig1_t;

    spiDAT1_t dataconfig1_t;

    dataconfig1_t.CS_HOLD = TRUE;                                // Specify if CS has to be held low for the full transmission.

    dataconfig1_t.WDEL    = FALSE;

    dataconfig1_t.DFSEL   = SPI_FMT_1;                            // Specify which data format to use. They are defined in Halcogen

    dataconfig1_t.CSNR    = 0xFE;

    pDataConfig1_t = &dataconfig1_t;

       transmitAllData[0] = ((((transmitAddress>>3))&0b01111111)|0x80);

       transmitAllData[1] = ((((transmitAddress<<5))&0b11100000)|0x10);

       transmitAllData[2] = transmitData;

       pTransmitData = &transmitAllData[0];

       enableSPI_CS0();

       spiTransmitData(spiREG3, pDataConfig1_t, 3, pTransmitData);

       disableSPI_CS0();

    }

    but we can live with this.

    2. The bigger problem is the Chip Select problem, we have tried a second board (with the scope connected to CS0) but the CS is not pulled down.  Here is what HalCoGen autogenerated here for spi.c/spi.h:

    Our transmit code is set with the data structure set up the way you suggested as above.

    dataconfig1_t.CS_HOLD = TRUE;                                // Specify if CS has to be held low for the full transmission.

    dataconfig1_t.WDEL    = FALSE;

    dataconfig1_t.DFSEL   = SPI_FMT_1;                            // Specify which data format to use. They are defined in Halcogen

    dataconfig1_t.CSNR    = 0xFE;

    Is there anything else that could keep this auto chipselect feature from working properly with the above dataconfig1_t configuration, where manually changing the registers does work?

    Thank you again. Here is the 4.03.00 HalCoGen library that was autogenerated we are using, where we see this issue (could there be a fix in the 4.04.00 version if we upgraded?) :  5621.HalCoGen.zip  

  • Tammy,


    I looked to your code and the only difference I can see is in the pinmux.
    I'm not doing anything special for MIBSPI3. All the pin we need are default function out of reset.
    I will try tomorrow my test code with MIBSPI3 checked in the pinmux tab.

    Just for information, I've you tried my code to see if the SPI3nCS0 is driven low?

    Also, because I really want to understand what is going on here, I've ordered and should receive tomorrow morning 2 Microchip board. The exact same one you are using.

    About the comment from Microchip, I think I understand why it is not working with our SPI in 12bit mode.
    Once the first 8 bit are in, they have to copy to some internal register (High address bit) They have to do the same for the second part of the address and finally for the data. If this is really the case, 1 key parameter is missing in their specification. Delay between 2 data (8bit).

    Maybe if the baudrate is extremely slow, during the low phase of SPI clock after bit8 they may have the time to do this internal housekeeping.

    I will let you know if I'm successful with my test.

  • Tammy,

    Here are some update. Good news for me, maybe bad news for you.

    I'm now working with the real module from Microchip.

    The setup is as following

    SPI3CLK     to SCK (6)
    SPI3nCS0   to CS_ (8)
    SPI3SIMO    to SDI (5)
    SPI3SOMI    to SDO (7)
    V3.3           to VIN (10)
    GND           to GND (12)

    The RESET_ is not connected (there is an internal pull up in the module)

    To validate and stress the setup, SPI3CLK is set to 10Mbauds.

    Here is my main code:

    void main(void)
    {
    /* USER CODE BEGIN (3) */
        spiDAT1_t dataconfig1_t;
        uint16 transmitAllData[3];
        uint16 receiveAllData[3];

        dataconfig1_t.CS_HOLD = TRUE;
        dataconfig1_t.WDEL    = FALSE;
        dataconfig1_t.DFSEL   = SPI_FMT_0;
        dataconfig1_t.CSNR    = 0xFE;

        spiInit();

        while(1)
        {
    // READ the SOFTRST REGISTER. Should read 0x00
            transmitAllData[0] = 0x54;                        //Physical address 0x2A
            transmitAllData[1] = 0x00;
            spiTransmitAndReceiveData(spiREG3, &dataconfig1_t, 2, transmitAllData, receiveAllData);

    // Write 0x07 to the SOFTRST REGISTER.
            transmitAllData[0] = 0x55;                        //Physical address 0x2A
            transmitAllData[1] = 0x07;
            spiTransmitData(spiREG3, &dataconfig1_t, 2, transmitAllData);

    // READ the SOFTRST REGISTER. Should read 0x00
            transmitAllData[0] = 0x54;                       //Physical address 0x2A
            transmitAllData[1] = 0x00;
            spiTransmitAndReceiveData(spiREG3, &dataconfig1_t, 2, transmitAllData, receiveAllData);

    // READ the TXMCR REGISTER. Should read 0x1C
            transmitAllData[0] = 0x22;                       //Physical address 0x11
            transmitAllData[1] = 0x00;
            spiTransmitAndReceiveData(spiREG3, &dataconfig1_t, 2, transmitAllData, receiveAllData);
        }
    /* USER CODE END */
    }

    The reason I'm reading TXMCR is because this register has bits set to 1 after reset. So reading the correct value validate the read path.

    In this test, I've also checked in Halcogen the pinmux option to be as close as possible with you setup.
    It is working as well. (again, there is no need to use the pinmux option for SPI3. All the signal used in this setup are the default signal out of reset)
    Pinmux is necessary when an alternate function is needed.

    At that point, I don't know what is really wrong with your setup.
    Are you using a custom board for your application (RM48 side) or one of our Development Board?
    I can have a look to your application code if you can share it. Use my private email.
    You can also call me if necessary.