This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: SPI send data


It's been a while since the last message. But I am still stuck on this
problem, which means that I am unable to control the programmable
potentiometer AD8400. So I have tried to check the pins with a logic
analyzer and it appears that I do not see any SPI clock. That is to
say that the pin PA5 is always low. As is the pin PA7. And PA8 is
always high. This pins correspond to the descriptions in the STM3210E
eval board http://www.st.com/stonline/products/literature/um/14220.pdf
. Am I missing some initialization step that should start off the
clock?

I have attached my code with this message. Please let me know if you
need more information.

Thank you,
Jayant

On Wed, Jun 1, 2011 at 19:19, Ilija Stanislevik <ilijas@siva.com.mk> wrote:
> On 06/01/2011 11:02 AM, jayant biswas wrote:
>> Hi Ilija,
>>
>> Thank you for your response to the previous question, I am using SPI1
>> and have changed the config accordingly and have noticed with a
>> voltmeter that the pin PA8 does stay high and goes low when the SPI is
>> active. I have another question now about sending data. If you take a
>> look at the timing diagrams on page 10 of the datasheet
>> (http://www.analog.com/static/imported-files/data_sheets/AD8400_8402_8403.pdf)
>> for the programmable potentiometer that I am using and then my code
>> below, could you maybe hint at what I am doing wrong?
>>
>> Regards,
>> Jayant
>>
>> So this code based on the loopback test that comes with the spi package in ecos.
>>
>> #include <cyg/infra/cyg_type.h>
>> #include <cyg/infra/testcase.h> ? ? ? ? // Test macros
>> #include <cyg/infra/cyg_ass.h> ? ? ? ? ?// Assertion macros
>> #include <cyg/infra/diag.h> ? ? ? ? ? ? // Diagnostic output
>>
>> #include <cyg/hal/hal_arch.h> ? ? ? ? ? // CYGNUM_HAL_STACK_SIZE_TYPICAL
>> #include <cyg/kernel/kapi.h>
>>
>> #include <cyg/io/spi.h> ? ? ? ? ? ? ? ? // Common SPI API
>> #include <cyg/io/spi_stm32.h> ? ? ? ? ? // STM32 data structures
>>
>> #include <string.h>
>>
>> //---------------------------------------------------------------------------
>> // Thread data structures.
>>
>> cyg_uint8 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL];
>> cyg_thread thread_data;
>> cyg_handle_t thread_handle;
>>
>> externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus2;
>>
>> //---------------------------------------------------------------------------
>> // SPI loopback device driver data structures.
>>
>> cyg_spi_cortexm_stm32_device_t loopback_device = {
>> ? ? .spi_device.spi_bus = &cyg_spi_stm32_bus1.spi_bus,
>> ? ? .dev_num = 0 , ? ? ? ? ? ? ? ? ? ? ?// Only 1 device.
>> ? ? .cl_pol = 1,
>> ? ? .cl_pha = 1,
>> ? ? .cl_brate = 8000000, ? ? ? ? ? ? ? ?// Nominal 8Mhz.
>> ? ? .cs_up_udly = 1,
>> ? ? .cs_dw_udly = 1,
>> ? ? .tr_bt_udly = 1,
>> ? ? .bus_16bit = true, // *** MODIFIED this because my data is 10 bits
>> };
>>
>> //---------------------------------------------------------------------------
>>
>> //const char tx_data[] = {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1}; // To set
>> maximum resistance at address 00
>> const char tx_data[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // To set
>> minimim resistance at address 00
>> const char tx_data1[] = "Testing extended API...";
>> const char tx_data2[] = "Testing extended API for a second transaction.";
>>
>> char rx_data [sizeof(tx_data)];
>> char rx_data1 [sizeof(tx_data1)];
>> char rx_data2 [sizeof(tx_data2)];
>>
>> //---------------------------------------------------------------------------
>> // Run single loopback transaction using simple transfer API call.
>>
>> void run_test_1 (cyg_bool polled)
>> {
>> ? ? diag_printf ("Test 1 : Simple transfer test (polled = %d).\n",
>> polled ? 1 : 0);
>> ? ? cyg_spi_transfer (&loopback_device.spi_device, polled, sizeof (tx_data),
>> ? ? ? ? (const cyg_uint8*) &tx_data[0], (cyg_uint8*) &rx_data[0]);
>>
>> ? ? diag_printf (" ? ?Tx data : %s\n", tx_data);
>> ? ? diag_printf (" ? ?Rx data : %s\n", rx_data);
>> ? ? CYG_ASSERT (memcmp (tx_data, rx_data, sizeof (tx_data)) == 0,
>> ? ? ? ? "Simple transfer loopback failed - mismatched data.\n");
>> }
>>
>>
>> //---------------------------------------------------------------------------
>> // Run all PL022 SPI interface loopback tests.
>>
>> void run_tests (void)
>> {
>> ? ? diag_printf ("Running STM32 SPI driver loopback tests.\n");
>> ? ? run_test_1 (true);
>> ? ? CYG_TEST_PASS_FINISH ("Loopback tests ran OK");
>> }
>>
>> //---------------------------------------------------------------------------
>> // User startup - tests are run in their own thread.
>>
>> void cyg_user_start(void)
>> {
>> ? ? CYG_TEST_INIT();
>> ? ? cyg_thread_create(
>> ? ? ? ? 10, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // Arbitrary priority
>> ? ? ? ? (cyg_thread_entry_t*) run_tests, ? ? ?// Thread entry point
>> ? ? ? ? 0, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//
>> ? ? ? ? "test_thread", ? ? ? ? ? ? ? ? ? ? ? ?// Thread name
>> ? ? ? ? &stack[0], ? ? ? ? ? ? ? ? ? ? ? ? ? ?// Stack
>> ? ? ? ? CYGNUM_HAL_STACK_SIZE_TYPICAL, ? ? ? ?// Stack size
>> ? ? ? ? &thread_handle, ? ? ? ? ? ? ? ? ? ? ? // Thread handle
>> ? ? ? ? &thread_data ? ? ? ? ? ? ? ? ? ? ? ? ?// Thread data structure
>> ? ? );
>> ? ? cyg_thread_resume(thread_handle);
>> ? ? cyg_scheduler_start();
>> }
>>
>> //=============================================================================
>>
> First you should change
>
> ? ?.cl_pol = 1,
> ? ?.cl_pha = 1,
>
> into
>
> ? ?.cl_pol = 0,
> ? ?.cl_pha = 0,
>
>
> in order to make STM32 SPI's timing compatible with potentiometer.
>
> Note that with cyg_spi_transfer() you can send/receive bytes or 16bit
> words, while your potentiometer expects 10bit words. You should take
> care to pack your 10bit word in 16bits (two consecutive bytes) aligned
> towards LS bit. That way STM32's SPI will clock out 6 unused bits at the
> beginning so at the end of transaction your 10 bits will settle in right
> place in potentiometer's shift register.
>
> const char tx_data[] = {0,0xff}; // To set maximum resistance at address 00
> const char tx_data[] = {0,0}; // To set minimum resistance at address 00
>
>
> In your attempt you are packing a bit in each byte (char) which is wrong.
>
> Also change
>
> ? ?.bus_16bit = true,
>
> into
>
> ? ?.bus_16bit = false,
>
> because you are sending/receiving in 8bit portions.
>
> Regards,
> --
>
> Ilija Stanislevik
> SIvA doo
> ul. Mladinska 43 lok. 6
> p.f. 53
> MK-2400 Strumica
> Macedonia
>
> www.siva.mk <http://www.siva.mk>
>
>
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/testcase.h>         // Test macros
#include <cyg/infra/cyg_ass.h>          // Assertion macros
#include <cyg/infra/diag.h>             // Diagnostic output

#include <cyg/hal/hal_arch.h>           // CYGNUM_HAL_STACK_SIZE_TYPICAL
#include <cyg/kernel/kapi.h>

#include <cyg/io/spi.h>                 // Common SPI API
#include <cyg/io/spi_stm32.h>           // STM32 data structures

#include <string.h>

//---------------------------------------------------------------------------
// Thread data structures.

cyg_uint8 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL];
cyg_thread thread_data;
cyg_handle_t thread_handle;

externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus1;

//---------------------------------------------------------------------------
// SPI loopback device driver data structures.

cyg_spi_cortexm_stm32_device_t loopback_device = {
    .spi_device.spi_bus = &cyg_spi_stm32_bus1.spi_bus,
    .dev_num = 0 ,                      // Only 1 device. 
    .cl_pol = 0,
    .cl_pha = 0,
    .cl_brate = 8000000,                // Nominal 8Mhz.
    .cs_up_udly = 1,
    .cs_dw_udly = 1,
    .tr_bt_udly = 1,
    .bus_16bit = false,
};

//---------------------------------------------------------------------------

//const char tx_data[] = {0,0,0,0,0,0,0,0,0,0};
//const char tx_data[] = {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1};
const char tx_data[] = {0,0xff};
//const char tx_data[] = "Testing, testing, 12, 123.";
const char tx_data1[] = "Testing extended API...";
const char tx_data2[] = "Testing extended API for a second transaction.";

char rx_data [sizeof(tx_data)];
char rx_data1 [sizeof(tx_data1)];
char rx_data2 [sizeof(tx_data2)];

//---------------------------------------------------------------------------
// Run single loopback transaction using simple transfer API call.

void run_test_1 (cyg_bool polled)
{
    diag_printf ("Test 1 : Simple transfer test (polled = %d).\n", polled ? 1 : 0);
    //cyg_spi_transfer (&loopback_device.spi_device, polled, sizeof (tx_data), 
    //    (const cyg_uint8*) &tx_data[0], (cyg_uint8*) NULL);
    cyg_spi_transfer (&loopback_device.spi_device, polled, sizeof (tx_data), 
        (const cyg_uint8*) &tx_data[0], (cyg_uint8*) NULL);

    diag_printf ("    Tx data : %s\n", tx_data);
    diag_printf ("    Rx data : %s\n", rx_data);
    CYG_ASSERT (memcmp (tx_data, rx_data, sizeof (tx_data)) == 0,
        "Simple transfer loopback failed - mismatched data.\n");
}

//---------------------------------------------------------------------------
// Run two loopback transactions using extended transfer API.

void run_test_2 (cyg_bool polled)
{
    diag_printf ("Test 2 : Extended API test (polled = %d).\n", polled ? 1 : 0);
    cyg_spi_transaction_begin (&loopback_device.spi_device);
    cyg_spi_transaction_transfer (&loopback_device.spi_device, polled, sizeof (tx_data1), 
        (const cyg_uint8*) &tx_data1[0], (cyg_uint8*) &rx_data1[0], false);
    cyg_spi_transaction_transfer (&loopback_device.spi_device, polled, sizeof (tx_data2), 
        (const cyg_uint8*) &tx_data2[0], (cyg_uint8*) &rx_data2[0], false);
    cyg_spi_transaction_end (&loopback_device.spi_device);

    diag_printf ("    Tx data 1 : %s\n", tx_data1);
    diag_printf ("    Rx data 1 : %s\n", rx_data1);
    diag_printf ("    Tx data 2 : %s\n", tx_data2);
    diag_printf ("    Rx data 2 : %s\n", rx_data2);
    CYG_ASSERT (memcmp (tx_data1, rx_data1, sizeof (tx_data1)) == 0,
        "Simple transfer loopback failed - mismatched data (transfer 1).\n");
    CYG_ASSERT (memcmp (tx_data2, rx_data2, sizeof (tx_data2)) == 0,
        "Simple transfer loopback failed - mismatched data (transfer 2).\n");
}

//---------------------------------------------------------------------------
// Run all PL022 SPI interface loopback tests.

void run_tests (void)
{
    diag_printf ("Running STM32 SPI driver loopback tests.\n");
    run_test_1 (true); 
    /*    run_test_1 (false); 
    run_test_2 (true); 
    run_test_2 (false); */
    CYG_TEST_PASS_FINISH ("Loopback tests ran OK");
}

//---------------------------------------------------------------------------
// User startup - tests are run in their own thread.

void cyg_user_start(void)
{
    CYG_TEST_INIT();
    cyg_thread_create(
        10,                                   // Arbitrary priority
        (cyg_thread_entry_t*) run_tests,      // Thread entry point
        0,                                    // 
        "test_thread",                        // Thread name
        &stack[0],                            // Stack
        CYGNUM_HAL_STACK_SIZE_TYPICAL,        // Stack size
        &thread_handle,                       // Thread handle
        &thread_data                          // Thread data structure
    );
    cyg_thread_resume(thread_handle);
    cyg_scheduler_start();
}

//=============================================================================
-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]