Implement code

Hi all

I have no coding experience but a friend helped me very fast to write a piece of code, he said would do the job i want to be done with my core module. I’ll post it here just to show, I’m not sure it’s perfectly correct but that’s not my problem. I don’t know how to get this code onto the 18f4685. As I’m not coding myself the world of compilers and files seems huge. I’ve tried to play around in MPLAB, sdcc skeleton, using example programs etc, but I’m not getting very close. I figured i need to include some mios files, a pic file? (452 only choice?) but how, where, more precise.

short said i need some kinda step by step help to make this code a working hex  :slight_smile: I’m into learning C so if i knew how to get code going with the MIOS i could go learning from there. I know it’s a pretty big question but also advice leading in the right direction is much appreciated!

As you can see (i guess  :)), the code is supposed to output a bunch of data which i´ll connect to several shift registers and then LED´s giving one LED for each button on a digital piano, via MIDI. Im posting the code mostly because it might be funnier for you coders ^^

Thank You

#include "cmios.h"
#include "pic18f452.h"

#define BIT_CLOCK	0
#define BIT_LATCH	1
#define BIT_DATA	2

#define CHANNEL	1
#define NOTEON	0x90
#define NOTEOFF	0x80

#define NOTE_OFFSET 15

#define BITASSIGN( bit, val ) PORTA = ( PORTA & ~( 1 << bit ) ) | ( val << bit );

unsigned char min( unsigned char a, unsigned char b )
{
	return a < b ? a : b;
}

unsigned char buffer[11];

void Init( )
{
	TRISA &= ~( ( 1 << BIT_CLOCK ) | ( 1 << BIT_LATCH ) | ( 1 << BIT_DATA ) );
}

void Delay( )
{
	int i=0;
	for( i; i<1000; ++i );
}

void ShiftBits( )
{
	BITASSIGN( BIT_CLOCK, 1 );
	Delay( );
	BITASSIGN( BIT_CLOCK, 0 );
}

void LatchRegisters( )
{
	BITASSIGN( BIT_LATCH, 1 );
	Delay( );
	BITASSIGN( BIT_LATCH, 0 );
}

void UpdateLeds( )
{
	unsigned char j=0;
	unsigned char bit=0;
	for( j; j<11; ++j )
		for( bit; bit<8; ++bit )
		{
			BITASSIGN( BIT_DATA, ( buffer[j] >> bit ) & 1 );
			ShiftBits( );
		}

	LatchRegisters( );
}

void OnNoteOn( unsigned char note )
{
	buffer[note >> 3] |= 1 << ( note & 7 );
	UpdateLeds( );
}

void OnNoteOff( unsigned char note )
{
	buffer[note >> 3] &= ~( 1 << ( note & 7 ) );
	UpdateLeds( );
}

void USER_MPROC_NotifyReceivedEvent( unsigned char evnt0, unsigned char evnt1, unsigned char evnt2 )
{
	if( ( ( NOTEOFF | CHANNEL ) == evnt0 ) || ( ( ( NOTEON | CHANNEL ) == evnt0 ) && ( 0 == evnt2 ) ) )
		OnNoteOff( min( 0x6C, evnt1 - NOTE_OFFSET ) );

	else if( ( NOTEON | CHANNEL ) == evnt0 )
		OnNoteOn( min( 0x6C, evnt1 - NOTE_OFFSET ) );
}

Thanks for sharing the source.

Yes, it’s a big question, BUT it’s been answered: http://www.midibox.org/dokuwiki/application_development

In that case i could try to be more specific. I was following those steps before, downloaded perl, sdcc and gputils, installed it correctly etc. Here the help stops in the docs and info i can found on all the midibox pages.

Running make.bat on the “empty” main.c in the /sdcc_skeleton/ works without error. I figured i could use this method and get it to work with some more code added. I get some error but there might just be coding errors left then?

I’m currently including cmios.h and pic18f452.h

EDIT: worked it down to just one error i think, what can that be?

Here´s the compiling:

[tt]

Compiling main.c

Processor: 18F452

main.c:103: error 65: function ‘Init’ already has body

main.c:110: error 103: code not generated for ‘Tick’ due to previous errors

main.c:118: error 103: code not generated for ‘Timer’ due to previous errors

main.c:129: error 103: code not generated for ‘DISPLAY_Init’ due to previous err

ors

main.c:138: error 103: code not generated for ‘DISPLAY_Tick’ due to previous err

ors

main.c:145: error 103: code not generated for ‘MPROC_NotifyReceivedEvnt’ due to

previous errors

main.c:153: error 103: code not generated for ‘MPROC_NotifyFoundEvent’ due to pr

evious errors

main.c:161: error 103: code not generated for ‘MPROC_NotifyTimeout’ due to previ

ous errors

main.c:168: error 103: code not generated for ‘MPROC_NotifyReceivedByte’ due to

previous errors

main.c:175: error 103: code not generated for ‘SR_Service_Prepare’ due to previo

us errors

main.c:182: error 103: code not generated for ‘SR_Service_Finish’ due to previou

s errors

main.c:190: error 103: code not generated for ‘DIN_NotifyToggle’ due to previous

errors

main.c:199: error 103: code not generated for ‘ENC_NotifyChange’ due to previous

errors

main.c:206: error 103: code not generated for ‘AIN_NotifyChange’ due to previous

errors

ERROR!

[/tt]

Hi fsvo,

Running make.bat on the “empty” main.c in the /sdcc_skeleton/ works without error. I figured i could use this method and get it to work with some more code added. I get some error but there might just be coding errors left then?

Just look at the first error:

[tt]main.c:103: error 65: function ‘Init’ already has body[/tt]

That tells you, that there are two Init() functions, and there are indeed:

  • from main.c the emtpy skeleton method: void Init() {}

  • from your code snippet: void Init() { TRISA &= ~( ( 1 << BIT_CLOCK ) | ( 1 << BIT_LATCH ) | ( 1 << BIT_DATA ) ); }

Just merge your code properly into main.c

Not sure about the USER_NotifyReceivedEvent() method in your snippet; I never worked with the USER_ namespace, maybe that’s okay - I’d use the MPROC_NotifyReceivedEvent() from main.c if it does not receive any MIDI Messages as expected

Best,

Michael

As for the compile error…

main.c:103: error 65: function ‘Init’ already has body

That’s your problem. Take a look at line 103. It’s your code:

void Init( )
{
	TRISA &= ~( ( 1 << BIT_CLOCK ) | ( 1 << BIT_LATCH ) | ( 1 << BIT_DATA ) );
}

Now look at line 35:

void Init(void) __wparam
{

}

Uh oh.

Now you *could* just rename your function to like… myinit() or something… but… All that bitbanging, you don’t need it. It’s in MIOS already. Scope out the LOAD SR stuff in the function reference :slight_smile:

Edit: Beaten. Hi AC :smiley:

hehe… S1 is back ;D

cheers, mate

Hahah I’m 10 pages of unread posts deep… ahhhh!

Good to see you bud :smiley:

Thanks guys, awesome, i shoud’ve figured that one out by myself. Im getting a sucessful compile that feels great. I will see later today how well it works after an upload, i guess not very good the first try  ;D

OK as i mentioned i’m using the 4685 with the 452.h file. Is this a problem? I tried upload the hex now but the display dies after rebooting MIOS and nothing seem to work. Actually even the sdcc skeleton 1.9 template program only running a “Hello World” on the display isn’t displaying a Hello World. I can’t find a .h file for 4685 anywhere on the net. Is this my problem anyway?

IMHO you have to edit the 452.h file; don’t think there’s a 685.h file around -

http://www.midibox.org/dokuwiki/mios_pic18f4685

Though I guess the PIC selection got easier with the latest MIOS releases, maybe stryd knows more about this?

I always took the easy way and bought 452’s instead  :wink:

best,

Michael

  • Use the pic18f4685.h provided with sdcc (or better pic18fregs.h if you can make portable code)

  • Don’t forget to fix the asm generated by sdcc with the provided perl script

  • Link with the following modified pic18f4685.lkr linker script

… and all should compile and work well!

pic18f4685.lkr :

// linker script for a MIOS project
// Thorsten Klose (tk@midibox.org), 2004-07-10

LIBPATH .

CODEPAGE  NAME=vectors    START=0x2C00        END=0x2FFF        PROTECTED
CODEPAGE  NAME=page      START=0x3000        END=0x17FFF
CODEPAGE  NAME=idlocs    START=0x200000      END=0x200007      PROTECTED
CODEPAGE  NAME=config    START=0x300000      END=0x30000D      PROTECTED
CODEPAGE  NAME=devid      START=0x3FFFFE      END=0x3FFFFF      PROTECTED
CODEPAGE  NAME=eedata    START=0xF00000      END=0xF003FF      PROTECTED

DATABANK  NAME=miosvars  START=0x000          END=0x00F
ACCESSBANK NAME=accessram  START=0x010          END=0x05F
DATABANK  NAME=gpr0      START=0x060          END=0x0FF
DATABANK  NAME=gpr1      START=0x100          END=0x1FF
DATABANK  NAME=gpr2      START=0x200          END=0x2FF
DATABANK  NAME=stack      START=0x300          END=0x37F          PROTECTED
DATABANK  NAME=miosram_u  START=0x380          END=0x5FF          PROTECTED
DATABANK  NAME=gpr3      START=0x600          END=0x6FF
DATABANK  NAME=gpr4      START=0x700          END=0x7FF
DATABANK  NAME=gpr5      START=0x800          END=0x8FF
DATABANK  NAME=gpr6      START=0x900          END=0x9FF
DATABANK  NAME=gpr7      START=0xA00          END=0xAFF
DATABANK  NAME=gpr8      START=0xB00          END=0xBFF
DATABANK  NAME=gpr9      START=0xC00          END=0xCFF
DATABANK  NAME=sfr13      START=0xD00          END=0xDFF          PROTECTED
DATABANK  NAME=sfr14      START=0xE00          END=0xEFF          PROTECTED
DATABANK  NAME=sfr15      START=0xF00          END=0xF5F          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED

SECTION    NAME=CONFIG    ROM=config

Thanks again. I also took the easy way and switched to a 452 and it’s working now :slight_smile: I will however look into your advice for other projects  ptitjes. Now i just need to work some more on the code, it’s not working exactly as intended with my shift register setup yet.

I will come back and show u the result of the porject when it’s done  :slight_smile:

i just need to work some more on the code, it’s not working exactly as intended with my shift register setup yet.

Uhm…

… All that bitbanging, you don’t need it. It’s in MIOS already. Scope out the LOAD SR stuff in the function reference :slight_smile:

Yes, I would also propose to use the integrated shift register handling of MIOS, it is *much* faster, and there are many C examples for the usage (see bottom of http://www.ucapps.de/mios_c.html)

In addition, it makes sense to play a little with the examples in order to get a feeling about the programming model.

What I’m missing in your C code is the initialisation of the IO pins at J5. By default these are analog pins, in order to enable the digital stage, following value has to be written into ADCON1:

ADCON1 = 0x07;

In addition, I would propose to set the pins directly on the following way:

LATAbits.RA0 = 1;

and

LATAbits.RA0 = 0;

This will result into a single instruction. The currently used “BITASSIGN” macro will probably generate 10 instructions or more

Anyhow, as mentioned above: try some programming examples first, and especially consider the usage of the natively supported SRIO chain

Best Regards, Thorsten.