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;
u3tb = c;
}
SPI_send_cmd(unsigned char c)
p4_0 = 0;
SPI4_send(unsigned short c)
while (ti_u4c1 == 0)
u4tb = c;
short unsigned
SPI4_receive(void) {
while (ri_u4c1 == 0)
return u4rb;
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
#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 */ );
sprintf((char *) buf, "SPI4 %04x ",c);
OLED_Show_String(1, buf, 10 /* left */ , 1*8 /* top */ );
OLED_Show_String(1, buf, 10 /* left */ , 2*8 /* top */ );
OLED_Show_String(1, buf, 10 /* left */ , 3*8 /* top */ );
OLED_Show_String(1, buf, 10 /* left */ , 4*8 /* top */ );
OLED_Show_String(1, buf, 10 /* left */ , 5*8 /* top */ );
OLED_Show_String(1, buf, 10 /* left */ , 6*8 /* top */ );
OLED_Show_String(1, buf, 10 /* left */ , 7*8 /* top */ );
hwsetup.c:
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdarg.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;
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
// 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;
// Enable VCC
p4_4 = 1;
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;
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
* Start the 32KHz crystal
cm04 = 1;
* Disable writing to CM0
* 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;
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
s_int(void)
if(++ticks % 48 == 0)
status.sek_flag=1;
SPI.c:
#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)
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;
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;
Hi, Tõnu,
seems like you forget that writing to PD9 and P9(i)S is protected by PRC2 bit. Please read carefully datasheet §10.1.
Yep, you saved my day again. Thanks!