Probably simple and stupid SPI problem

Hi!

Sometimes simple things are most time consuming. I have two similar SPI ports 3 and 4 on R32C/111 100pin version. Port 3 where OLED is connected works, Port 4 pins are always low and won't work.

Probably something too simple to see and messing for hours already, so I ask for help.

main.c:

#include "types.h"

#include "ior32c111.h"

#include <stdio.h>

#include "main.h"

#include "hwsetup.h"

volatile unsigned short ticks;

extern int alarm;

#define SPI_DELAY (50)

void

SPI_send_data(unsigned char c)

{

    while (ti_u3c1 == 0)

        NOP();

    uDelay(SPI_DELAY);

    p4_0 = 1;

    uDelay(SPI_DELAY);

    u3tb = c;

}

void

SPI_send_cmd(unsigned char c)

{

    while (ti_u3c1 == 0)

        NOP();

    uDelay(SPI_DELAY);

    p4_0 = 0;

    uDelay(SPI_DELAY);

    u3tb = c;

}

void

SPI4_send(unsigned short c)

{

    while (ti_u4c1 == 0)

        NOP();

    uDelay(SPI_DELAY);

    u4tb = c;

}

short unsigned

SPI4_receive(void) {

    while (ri_u4c1 == 0)

        NOP();

    uDelay(SPI_DELAY);

    return u4rb;

}

void

main(void) {

    HardwareSetup();

    OLED_Set_Display_Mode(0x02);                           // Entire Display On

    OLED_Set_Display_On_Off(0x01);                         // Display On

    OLED_Show_Logo();

    while (1) {

        if (status.sek_flag) {

            char buf[256];

            status.sek_flag=0;

              LED1 ^= 1;

SPI4_send(0xAA);

SPI4_send(0xFF);

#if 1

SPI4_send(0xFF);

SPI4_send(0xFF);

SPI4_send(0xFF);

SPI4_send(0xFF);

SPI4_send(0xFF);

SPI4_send(0xFF);

SPI4_send(0xFF);

#endif

            unsigned short c; /* 16 bit value */

            c=SPI4_receive();

            sprintf( /*(char *)*/ buf, "%s%s%s%s%s SPI4 %04x ",

                    (c & (1 << 11)) ? "Arbitration " : "",

                    (c & (1 << 12)) ? "Overrun " : "",

                    (c & (1 << 13)) ? "Framing " : "",

                    (c & (1 << 14)) ? "Parity " : "",

                    (c & (1 << 15)) ? "Sum " : "", c);

            OLED_Show_String(1, buf, 10 /* left */ , 0*8 /* top */ );

            c=SPI4_receive();

            sprintf((char *) buf, "SPI4 %04x ",c);

            OLED_Show_String(1, buf, 10 /* left */ , 1*8 /* top */ );

            c=SPI4_receive();

            sprintf((char *) buf, "SPI4 %04x ",c);

            OLED_Show_String(1, buf, 10 /* left */ , 2*8 /* top */ );

            c=SPI4_receive();

            sprintf((char *) buf, "SPI4 %04x ",c);

            OLED_Show_String(1, buf, 10 /* left */ , 3*8 /* top */ );

            c=SPI4_receive();

            sprintf((char *) buf, "SPI4 %04x ",c);

            OLED_Show_String(1, buf, 10 /* left */ , 4*8 /* top */ );

            c=SPI4_receive();

            sprintf((char *) buf, "SPI4 %04x ",c);

            OLED_Show_String(1, buf, 10 /* left */ , 5*8 /* top */ );

            c=SPI4_receive();

            sprintf((char *) buf, "SPI4 %04x ",c);

            OLED_Show_String(1, buf, 10 /* left */ , 6*8 /* top */ );

            c=SPI4_receive();

            sprintf((char *) buf, "SPI4 %04x ",c);

            OLED_Show_String(1, buf, 10 /* left */ , 7*8 /* top */ );

        }

    }

}

hwsetup.c:

#include "types.h"

#include "ior32c111.h"

#include "hwsetup.h"

#include <stdio.h>

#include <string.h>

#include <stddef.h>

#include <stdlib.h>

#include <stdarg.h>

#include "main.h"

/*

* These functions are private so their prototypes are defined locally

*/

static void ConfigureOperatingFrequency(char mode);

static void ConfigurePortPins(void);

unsigned char seklo;

volatile struct statuses status;

unsigned int base_freq;

void

OLED_On(void)

{

    // Make ports safe

    p4_0 = 0;                                              // DC (data/command)

    p4_2 = 0;                                              // reset pin

    p4_4 = 0;                                              // VCC pin

    p4_5 = 0;                                              // VDD is reversed (0-on, 1-off), but switched ON first, so keep it like that  happy

    // Port function is IO

    p4_0s = 0;

    p4_2s = 0;

    p4_4s = 0;

    p4_5s = 0;

    // Ports are output

    pd4_0 = 1;                                             // Reset pin

    pd4_2 = 1;                                             // Reset pin

    pd4_4 = 1;                                             // VCC

    pd4_5 = 1;                                             // VDD

    // Make sure VDD is ON

    p4_4 = 0;

    uDelay(10);

    // Reset sequence

    p4_2 = 1;

    uDelay(100);

    p4_2 = 0;

    uDelay(100);

    p4_2 = 1;

    uDelay(100);

    // Enable VCC

    p4_4 = 1;

    uDelay(100);

}

void

HardwareSetup(void)

{

    /*

     * Configures CPU clock

     */

    DISABLE_IRQ;

    ConfigureOperatingFrequency(1);

    // Init_TMRA0 1 mS timer

    ta3mr = 0x80;                                          // timer mode,fc/8 = 1,0 MHz

    ta3 = 24;                                              // 1MHz/25 - 1; 48 oli Fi = 40kHz

    ta3ud = 0;                                             // down count

    ta3ic = 2;                                             // level 2 interrupt

    ta3s = 1;

    ticks = 0;

    // Init_TMRB5 1 mS timer

    tb5mr = 0x80;                                          // timer mode,fc/8 = 1,0 MHz

    tb5 = 9999;                                            // 1MHz/25 - 1; Fi = 40kHz

    tb5ic = 1;                                             // level 1 interrupt

    tb5s = 1;

    ticks = 0;

    ConfigurePortPins();

    SPI3_Init(); // OLED?

    SPI4_Init(); // Melexis sensor

    OLED_On();

    OLED_Init();

    ENABLE_IRQ;

}

static void

ConfigureOperatingFrequency(char mode)

{

    unsigned short i;

        prr = 0xAA;

        ccr = 0x1F;

        prr = 0x00;

        prc0 = 1;

        pm3 = 0x40;                                        // peripheral clock 24MHz

        prc0 = 0;

        prc2 = 1;

        *(unsigned short *) &plc0 = 0x0226;                // 48MHz, PLL = 96MHz

        prc2 = 0;

        base_freq = 24000000;

    for (i = 0; i < 0x8000u; i++);                         /* Add delay

                                                            * for PLL to

                                                            * stabilise. */

    /*

     * Disable the port pins

     */

    pd8_7 = 0;

    pd8_6 = 0;

    /*

     * Disable the pull-up resistor

     */

    pu25 = 0;

    /*

     * Enable writing to CM0

     */

    prc0 = 1;

    /*

     * Start the 32KHz crystal

     */

    cm04 = 1;

    /*

     * Disable writing to CM0

     */

    prc0 = 0;

    /*

     * Enable writing to PM2

     */

    prc1 = 1;

    /*

     * Disable clock changes

     */

    pm21 = 1;

    pm26 = 1;                                             

    /*

     * Disable writing to PM2

     */

    prc1 = 0;

    cst_tcspr = 0;

    tcspr = 0x08;

    cst_tcspr = 1;                                       

}

static void

ConfigurePortPins(void)

{

    /*

     * All pins are input by default

     */

    pur0 = 0;                           

    pd0 = pd1 = 0;                               

    p0 = p1 = 0;

    p0_0s = p0_1s = p0_2s = p0_3s = p0_4s = p0_5s = p0_6s = p0_7s = 0;

    p1_0s = p1_1s = p1_2s = p1_3s = p1_4s = p1_5s = p1_6s = p1_7s = 0;

    p2 = 0x07;   

    pd2 = 0x0F;                            

    p2_0s = p2_1s = p2_2s = p2_3s = 0;

    p2_4s = p2_5s = p2_6s = p2_7s = 0x80;

    p3 = 0;                                                

    pd3 = 0xAB;                                           

    p3_0s = p3_1s = p3_3s = p3_5s = p3_7s = 0;

    p3_2s = p3_4s = p3_6s = 0x02;

    pur1 = 0x04;       

    pd5 = 0x80;                                          

    p5_0s = p5_1s = p5_2s = p5_3s = p5_5s = p5_7s = 0;

    p5_6s = p5_4s = 0x03;

    p5 = 0;                                                //

    // P6_4...P6_7 is E8a

    pur2 = 0;      

    pd6_0 = 0;

    pd6_1 = 0;

    pd6_2 = 0;

    pd6_3 = 0;

    p6_2s = 3;

    p6_3s = 3;

    pd7 = 0x90;                                           

    p7 = 0;                                              

    p7_0s = p7_1s = p7_3s = p7_5s = p7_6s = 3;            

    p7_2s = p7_4s = p7_7s = 0;                            

    pd8 = 2;                                              

    p8 = 0;

    p8_0s = 3;

    p8_1s = 0;

    p8_2s = 0;                                            

    p8_3s = 0;                                            

    pd8_4 = 0;                                            

    p8_4s = 0;                                            

    pu24 = 1; 

    pd10 = 0;                                             

    p10 = 0;

    p10_1 = 0;

    p10_0s = p10_1s = p10_2s = p10_3s = p10_4s = p10_5s = p10_6s = p10_7s = 0x80;

    pd9=0xff;

    p9=0xff;

}

// 1000 Hz interrupt

#pragma vector=TIMER_A3

__interrupt void

ms_int(void)

{

}

#pragma vector=TIMER_B5

__interrupt void

s_int(void)

{

    if(++ticks % 48 == 0)

      status.sek_flag=1;

}

SPI.c:

#include "types.h"

#include "ior32c111.h"

#include <intrinsics.h>

#define PDIR_INPUT    (0)

#define PDIR_OUTPUT    (1)

#define PF_SPI_CLK    (p4_1s)

#define PF_SPI_DATA   (p4_3s)

#define PF_SPI        (3)

void

SPI4_Init(void)

{

    /*

     * CS

     */

    pd9_4 = PDIR_OUTPUT;

    /*

     * CLK4

     */

    pd9_5 = PDIR_OUTPUT;

    p9_5s = PF_SPI;

    /*

     * TXD4

     */

    pd9_6 = PDIR_OUTPUT;

    p9_6s = PF_SPI;

    smd0_u4mr  = 1;                                        // \

    smd1_u4mr  = 0;                                        //  | Synchronous Serial Mode

    smd2_u4mr  = 0;                                        // /

    ckdir_u4mr = 0;                                        // 0=internal clock

    stps_u4mr  = 0;                                        // 0=1 stop bit, 0 required

    pry_u4mr   = 0;                                        // Parity, 0=odd, 0 required

    prye_u4mr  = 0;                                        // Parity Enable? 0=disable, 0 required

    iopol_u4mr = 0;                                        // IO Polarity, 0=not inverted, 0 required

    clk0_u4c0 = 0;                                         // Clock source f1 for u4brg

    clk1_u4c0 = 0;                                         //

    txept_u4c0 = 0;                                        // Transmit register empty flag

    crd_u4c0 = 1;                                          // CTS disabled when 1

    nch_u4c0 = 0;                                          // 0=Output mode "push-pull" for TXD and CLOCK pin

    ckpol_u4c0 = 0;                                        // CLK Polarity

    uform_u4c0 = 1;                                        // 1=MSB first

    te_u4c1 = 1;                                           // 1=Transmission Enable

    ti_u4c1 = 0;                                           // Must be 0 to send or receive

    re_u4c1 = 1;                                           // Reception Enable when 1

    ri_u4c1 = 1;                                           // Receive complete flag - U4RB is empty.

    u4irs_u4c1 = 0;                                        // Interrupt  when transmission  is completed, U4TB is empty.

    u4rrm_u4c1 = 1;                                        // Continuous receive mode off

    u4lch_u4c1 = 0;                                        // Logical inversion off

    u4smr = 0x00;                                          // Set 0

    u4smr2 = 0x00;                                         // Set 0

    sse_u4smr3 = 0;                                        // SS is disabled when 0

    ckph_u4smr3 = 0;                                       // Non clock delayed

    dinc_u4smr3 = 0;                                       // Master mode when 0

    nodc_u4smr3 = 0;                                       // Select a clock output  mode "push-pull" when 0

    err_u4smr3 = 0;                                        // Error flag, no error when 0

    dl0_u4smr3 = 0;                                        // Set 0 for no  delay

    dl1_u4smr3 = 0;                                        // Set 0 for no  delay

    dl2_u4smr3 = 0;                                        // Set 0 for no  delay

    u4smr4 = 0x00;                                         // Set 0. u4c0 must be set before this function

    u4brg = 10;                                             // (unsigned char)(((f1_CLK_SPEED)/(2*BIT_RATE))-1);

    s4tic = 0x0;

}

void

SPI3_Init(void)

{

    /*

     * CLK3

     */

    pd4_1 = PDIR_OUTPUT;

    PF_SPI_CLK = PF_SPI;

    /*

     * TXD3

     */

    pd4_3 = PDIR_OUTPUT;

    PF_SPI_DATA = PF_SPI;

    smd0_u3mr = 1;                                        // \

    smd1_u3mr = 0;                                         // >    // Synchronous Serial Mode

    smd2_u3mr = 0;                                         // /

    ckdir_u3mr = 0;                                        // internal clock , 243

    stps_u3mr = 0;                                         // 0 required

    pry_u3mr = 0;                                          // 0 required

    prye_u3mr = 0;                                         // 0 required

    iopol_u3mr = 0;                                        // 0 required

    clk0_u3c0 = 0;                                         // \ Clock

    clk1_u3c0 = 0;                                         // /

    txept_u3c0 = 0;                                        // Transmit

    crd_u3c0 = 1;                                          // CTS disabled

    nch_u3c0 = 0;                                          // Output mode

    ckpol_u3c0 = 0;                                        // Polarity

    uform_u3c0 = 1;                                        // MSB first

    te_u3c1 = 1;                                           // Transmission

    ti_u3c1 = 0;                                           // Must be 0 to

    re_u3c1 = 0;                                           // Reception is

    ri_u3c1 = 0;                                           // Receive

    u3irs_u3c1 = 0;                                        // 1 when

    u3rrm_u3c1 = 1;                                        // Continuous

    u3lch_u3c1 = 0;                                        // Logical

    u3smr = 0x00;                                          // Set 0

    u3smr2 = 0x00;                                         // Set 0

    sse_u3smr3 = 0;                                        // SS is

    ckph_u3smr3 = 0;                                       // Non clock

    dinc_u3smr3 = 0;                                       // Master mode

    nodc_u3smr3 = 0;                                       // Select a

    err_u3smr3 = 0;                                        // Error flag,

    dl0_u3smr3 = 0;                                        // Set 0 for no

    dl1_u3smr3 = 0;                                        // Set 0 for no

    dl2_u3smr3 = 0;                                        // Set 0 for no

    u3smr4 = 0x00;                                         // Set 0 (page

    u3brg = 3;                                            

    s3tic = 0x0;

}