![]() |
Forum Index : Microcontroller and PC projects : PicoMite V5.07.01b16: Breaking changes and CSUBs
Page 1 of 3 ![]() ![]() |
|||||
Author | Message | ||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10041 |
PicoMiteV5.07.01b16.zip Breaking change to PINCTRL function GP prefix is now mandatory for start pin parameters. Normal pin numbers can not be used in this function Breaking changes to SETPIN, to improve compatibility with other MMBasic variants SETPIN n, m, COM1 ' allocates UART0 pins to COM1. If the pins don't form a UART0 RX/TX pair then errors, pin order is not important SETPIN n, m, COM2 ' allocates UART1 pins to COM2. If the pins don't form a UART1 RX/TX pair then errors, pin order is not important SETPIN n, m, p, SPI 'allocates SPI0 pins to SPI. If the pins don't form a SPI0 RX/TX/CLK triple then errors, pin order is not important SETPIN n, m, p, SPI2 'allocates SPI1 pins to SPI2. If the pins don't form a SPI1 RX/TX/CLK triple then errors, pin order is not important SETPIN n, m, I2C ' allocates I2C0 pins to I2C. If the pins don't form a I2C0 SDA/SCL pair then errors, pin order is not important SETPIN n, m, I2C2 ' allocates I2C1 pins to I2C2. If the pins don't form a I2C1 SDA/SCL pair then errors, pin order is not important Commands are then OPEN "COM1:baud" OPEN "COM2:baud" SPI command and function SPI2 command and function I2C command I2C2 command PWM will remain unchanged. i.e. SETPIN n, PWMna where n=0-7 and a=AorB. This reflects the fact on the PicoMite that you can use a PWM B channel without an A unlike any other MM e.g PWM 0,1000,,50 CSUbs See here for more info Commands to compile and link for the PicoMite assuming the source file is main.c are arm-none-eabi-gcc -c -mcpu=cortex-m0 -mfloat-abi=soft -mthumb -Wall -Wno-main -ffunction-sections -O0 -fPIC -I. main.c -o main.o arm-none-eabi-ld -nostartfiles -T arm-gcc-link.ld -o main.elf main.o MMBasic for DOS program to convert the .elf file to the Basic statements: armcfgenV143.zip Header file for linking in internal routines (untested): PicoCFunctions.zip Example source file: void strrev(unsigned char in[], unsigned char out[]) { unsigned int i; unsigned int len; //MMBasic stores the length of the string in the //first,0th,byte len=in[0]; //Set the length of the output string out[0]=len; //Do the reverse copy for(i=1;i<(len+1);i++){ out[i]=in[len-i+1]; } //and return the length of the string } void main(void){} Compiled output and demo Dim a$="1234567890" Dim b$ strrev a$,b$ Print b$ CSub strrev 00000000 B085B480 6078AF00 687B6039 60BB781B B2DA68BB 701A683B 60FB2301 68BAE00D 1AD368FB 687A3301 6839441A 440B68FB 701A7812 330168FB 68BB60FB 68FA3301 D3EC429A BF00BF00 46BD3714 4770BC80 End CSub Bug fixes Fixed bug in LONGSTRING RESIZE Outstanding issues I haven't looked at led-bloons PIO issue yet Coming next (hopefully) The ability to define a CSUB which will run stand-alone on the second processor Edited 2021-09-12 22:39 by matherp |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7490 |
Updated TINAM in line with above changes to PINCTRL and SETPIN just for completeness. :) PicoMite TINAM doc 0912.zip Edited 2021-09-12 23:23 by Mixtel90 Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
thwill![]() Guru ![]() Joined: 16/09/2019 Location: United KingdomPosts: 4249 |
Very nice ... I look forward to escaping from my Linux port and drifting back onto the Pico for a while. Best wishes, Tom MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7490 |
LIST FUNCTIONS shows MM.Info( but also MM.Info$( 3 times. Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10041 |
Oops PicoMiteV5.07.01b16.zip |
||||
Mixtel90![]() Guru ![]() Joined: 05/10/2019 Location: United KingdomPosts: 7490 |
>Phew!< Having said that... strange error caused by fat fingers: > setpin 2,1,c0m1 Error : 0 is invalid (valid is 8 to 12) With thinner fingers it seems to work. reversing 1 & 2 gives the expected error. > setpin 1,2,c0m1 Error : Invalid configuration . Edited 2021-09-13 04:23 by Mixtel90 Mick Zilog Inside! nascom.info for Nascom & Gemini Preliminary MMBasic docs & my PCB designs |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4836 |
@Peter The current ADC command is very nice in respect that it can run in the background. You get an interrupt when the array is filled with data. This is perfect for taking a single shot sample run. If you however want to take continuous samples the best I can do with the current command is alternating (ping-pong) buffers (pseudo code) set an intterupt start the adc filling array a() buffer = 1 in the interrupt if buffer=1 restart the adc filling array b(): buffer = 2 else restart the adc filling array a(): buffer = 1 in the main process either a() or b() while the other is filled. Or do you see a better way ? The ADC does not support "round robin" on the array correct ? Can de ADC handle multidimensional arrays ? something like ADC START array( ,n) where n is alternating between 0 an 1 in above example ? About MATH, I can use MATH ADD and MATH SCALE to calculate the actual measured value of each sample (in single dimensional arrays), is there any function in the MATH range I can use to find the MIN and MAX value (other than a MMbasic FOR/NEXT loop) ? My current code has loads of for-next loops to process all the data, and I want to speed things up by using the MATH commands. Thanks in advance for your answer, Volhout Edited 2021-09-13 17:07 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10041 |
That is currently the best approach ? math(max a()) ? math(min a()) Check the CMM2 manual. The MATH command and function on the PicoMite are identical Edited 2021-09-13 17:27 by matherp |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4836 |
Hi Peter, EDIT: I removed the original text, since it was my oops. I had OPTION BASE set to 0. Where as I used 1 as the first element in arrays. However... I found something other that I needs advise on. Option base 1 n=1000 Dim a(n),b(n) 'fill array with sine wave Timer = 0 For i=1 To n a(i)=Sin(Pi*i/(n/5)) Next i Print "fill array sine funct ";Timer 'calculate min, max, mean from array Timer = 0 p = Math(Max a()) l = Math(min a()) m = Math(mean a()) Print "max,min,mean math() ";Timer Print "max = ";p;" min = ";l;" mean = ";m 'calculate min max mean classical way Timer = 0 p=0:l=0:m=0 For i= 1 To n p = Max(a(i),p) l = Min(a(i),l) m = m+a(i) m = m / n Next i Print "max,min,mean classic ";Timer Print "max = ";p;" min = ";l;" mean = ";m fill array sine funct 119.462 max,min,mean math() 6.267 max = 1 min = -1 mean = 0.1273213365 max,min,mean classic 244.606 max = 1 min = -1 mean = 1.573877524e-08 the classical way, the mean value of this 5 cycle sine wave is 1.5e-8 (rounding error). But using the Math(Mean) function the error is larger. Edited 2021-09-13 19:20 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10041 |
Can't replicate: I get the same answer in all three calcs (b16) - replying to first question - will look at second Edited 2021-09-13 19:25 by matherp |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4836 |
Sorry.... The mean of 5 cycles is 0, the mean of 5 half-cycles is 1/5 of sqr(1/2) is 0.12... I filled the array with 5 half cycles. 360 degrees is 2*pi, not pi. I will hide into the corner with my tail between my legs and lick my wounds. Deeply ashamed... Volhout Edited 2021-09-13 19:37 by Volhout PicomiteVGA PETSCII ROBOTS |
||||
disco4now![]() Guru ![]() Joined: 18/12/2014 Location: AustraliaPosts: 969 |
Hi Peter, Here is an updated PicoCFunctions.h header file. PicoCFunctions.zip It contains changes I discovered when testing CSUBs which accessed the MMBasic functions via the header file on the ArmmiteF4 and I have made same corrections to this file. See the ArmmiteF4 CSUBs link for more information. V1.6 Added parenthesis around (BaseAddress+0xx) expressions to force correct evaluation Option Macro now --> #define Option (*(struct option_s *)(unsigned int)Vector_Option) Added two useful #defines #define NOP() __asm volatile ("nop") #define USERLCDPANEL 16 The code and CSUB below where used to verify the header file. Its a crude display driver that just prints that the DrawRectangle and DrawBitMap routines have been called. They also set HRes,VRes and Display_TYPE to prove they work. Issue with uSec() I think there is an issue with the uSec() call. The CSUB hangs when it is called. I accidently discovered a workaround, it does not hang if a putConsole() call is made before the uSec() called e.g. //workaround for uSec() issue. Hangs without putConsole() void myuSec(unsigned int a){ putConsole(0); uSec(a); } This may help to discover the cause. Another thing I notice was setting a USER panel i.e. OPTION LCDPANEL USER ,320,240 was that HRes and VRes are set and available to the driver. However if they are updated via the CSUB that OPTION LIST will always show the original values entered with the OPTION LCDPANEL USER command. If no OPTION USER LCDPANEL is used the HRes and VRes dont show in OPTION LIST, even though they are set in the CSUB, and readable as there correct values in the CSUB. /* * File: main.c */ /* ArmmiteF4 compiler and linker command parameters arm-none-eabi-gcc -c -mcpu=cortex-m4 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -Wall -Wno-main -ffunction-sections -O0 -fPIC -I. main.c -o main.o arm-none-eabi-ld -nostartfiles -T arm-gcc-link.ld -o main.elf main.o PicoMite compiler and linker command parameters arm-none-eabi-gcc -c -mcpu=cortex-m0 -mfloat-abi=soft -mthumb -Wall -Wno-main -ffunction-sections -O0 -fPIC -I. main.c -o main.o arm-none-eabi-ld -nostartfiles -T arm-gcc-link.ld -o main.elf main.o */ /* Uncomment the relevant #define statement to use the required code */ //#define ST7789 //#define QUICKSORT //#define STRREV #define HEADERTEST /**********************************************/ #include "../inc/PicoCFunctions.h" #ifdef HEADERTEST void HEADERTEST_v100(){ NOP(); //Padding to make sure it ends on 4 byte boundary } void p_string(const char *s){ char * testData = ( char *)((void *)s ); MMPrintString(testData); } void p_int(int a,int base){ char b[64]; IntToStr(b,a,base); MMPrintString(b);putConsole(32); } /******************************************************************** * DrawRectangle in MMBasic is redirected to this function * this is the basic drawing primitive used by most drawing routines * x1, y1, x2, y2 - the coordinates * c - the colour * ------------------------------------------------------ * ***** MUST BE static void for the ARMMITEF4 ********** * ------------------------------------------------------ * *********************************************************************/ static void DrawRectangleSPI(int x1, int y1, int x2, int y2, int c){ static const char s4[]="DrawRectangle Called to set Option.DISPLAY_TYPE "; static const char crlf[]="\r\n"; p_string(s4);p_int(c,10); p_string( crlf); Option.DISPLAY_TYPE=c; } /******************************************************************** * DrawBitMap in MMBasic is redirected to this function * Prints the bitmap of a char * x, y - the top left of the char * width, height - size of the char's bitmap * scale - how much to scale the bitmap * fc, bc - foreground and background colour * bitmap - pointer to the bitmap * ------------------------------------------------------ * ***** MUST BE static void for the ARMMITEF4 ********** * ------------------------------------------------------ * **********************************************************************/ static void DrawBitmapSPI(int x1, int y1, int width, int height, int scale, int fc, int bc, unsigned char *bitmap){ static const char s5[]="DrawBitmap Called to set HRes and VRes "; static const char crlf[]="\r\n"; p_string(s5);p_int(x1,10);p_int(y1,10); p_string(crlf); HRes=x1; VRes=y1; } //workaround for uSec() issue. Hangs without putConsole() void myuSec(unsigned int a){ putConsole(0); uSec(a); } void main(long long *CD, long long *RST, long long *CS,long long *orientation){ int HorizontalRes=240,VerticalRes=240; Option.LCD_Reset=*RST; Option.LCD_CD=*CD; Option.LCD_CS=*CS; Option.DISPLAY_ORIENTATION=*orientation; Option.DISPLAY_TYPE=USERLCDPANEL ; if(ExtCurrentConfig[(int) Option.LCD_Reset]!=EXT_BOOT_RESERVED){ExtCfg(Option.LCD_Reset,EXT_DIG_OUT,0);} //if(ExtCurrentConfig[(int) Option.LCD_Reset]!=EXT_BOOT_RESERVED){ExtCfg(Option.LCD_Reset,EXT_DIG_OUT,0);ExtCfg(Option.LCD_Reset,EXT_BOOT_RESERVED,0);} PinSetBit(Option.LCD_Reset, LATSET); if(ExtCurrentConfig[(int) Option.LCD_CD]!=EXT_BOOT_RESERVED){ExtCfg(Option.LCD_CD,EXT_DIG_OUT,0);} //if(ExtCurrentConfig[(int) Option.LCD_CD]!=EXT_BOOT_RESERVED){ExtCfg(Option.LCD_CD,EXT_DIG_OUT,0);ExtCfg(Option.LCD_CD,EXT_BOOT_RESERVED,0);} PinSetBit(Option.LCD_CD, LATSET); if(ExtCurrentConfig[(int) Option.LCD_CS]!=EXT_BOOT_RESERVED){ExtCfg(Option.LCD_CS,EXT_DIG_OUT,0);} //if(ExtCurrentConfig[(int) Option.LCD_CS]!=EXT_BOOT_RESERVED){ExtCfg(Option.LCD_CS,EXT_DIG_OUT,0);ExtCfg(Option.LCD_CS,EXT_BOOT_RESERVED,0);} PinSetBit(Option.LCD_CS, LATSET); //Reset the ST7789 PinSetBit(Option.LCD_Reset,LATSET);myuSec(10000); PinSetBit(Option.LCD_Reset,LATCLR);myuSec(100000); PinSetBit(Option.LCD_Reset,LATSET);myuSec(200000); // spi_write_command(ST77XX_SWRESET);uSec(150000); // spi_write_command(ST77XX_SLPOUT);uSec(500000); // spi_write_command(ST77XX_COLMOD);spi_write_data(0x55);uSec(10000); if(Option.DISPLAY_ORIENTATION&1){ VRes=HorizontalRes; HRes=VerticalRes; } else { HRes=HorizontalRes; VRes=VerticalRes; } //update original Vectors to point to our new functions //Set the DrawBitmap vector to point to our function // Called each time the TEXT command writes a character DrawBitmapVector=(unsigned int)&DrawBitmapSPI; //Set the DrawRectangle vector to point to our function // Called when any of the GUI commands writes to screen.(Also CLS) DrawRectangleVector= (unsigned int)&DrawRectangleSPI; //CLS //DrawRectangle(0,0,HRes-1,VRes-1,0x000000); static const char startup[]="HEADERTEST LOADED\r\n"; static const char crlf[]="\r\n"; static const char s1[]="First parameter = "; static const char s2[]="Second parameter = "; static const char s3[]="Third parameter = "; static const char s6[]="HRes,VRes,DISPLAY_TYPE,Brightness = "; p_string(startup); p_string(s1); p_int(Option.LCD_CD,10); p_string(crlf); p_string(s2);p_int(Option.LCD_Reset,10); p_string(crlf); p_string(s3); p_int(Option.LCD_CS,10); p_string(crlf); p_string(s6); p_int(HRes,10);p_int(VRes,10);p_int(Option.DISPLAY_TYPE,10);p_int(Option.DefaultBrightness,10); p_string(crlf); } #endif Here is a STMCubeIDE project I use to edit the main.c You can test compile and use the IDE. When error free I then use the recommend parameters and compile to generate the ELF and CSUB. myPicoCSUBS.zip Edited 2021-09-13 22:04 by disco4now Latest F4 Latest H7 FotS |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10041 |
Please could you see if this fixes the uSec issue PicoMite.zip |
||||
disco4now![]() Guru ![]() Joined: 18/12/2014 Location: AustraliaPosts: 969 |
No, does not fix it. Still hangs without the putConsole() work around. Regards Gerry Latest F4 Latest H7 FotS |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4836 |
@Peter, A practical question. MATH(MAX a()) gives the maximum value in the array. But is there any way to retrieve the index (pointer) at which the maximum is found ? This is of coarse tricky if it is a multi dimension array. Actually, now I think of it, returning the pointer is even more logical than returning the value, since it is easy to read the value once you have the pointer. The opposite is not possible. Regards, Volhout PicomiteVGA PETSCII ROBOTS |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10041 |
PicoMiteV5.07.01b17.zip Fixes a bug in the uSec function. NB: the header file also needs changing #define uSec(a) ((void (*)(unsigned long long )) Vector_uSec) (a) New optional parameter for the MATH(MIN and MATH(MAX functions MATH(MAX array() [,index%]) MATH(MIN array() [,index%]) If index% is included in the function call then it will be updated with the index into the array that was the maximum or minimum. This only works for single dimension arrays. Attempting to use it on multidimensional arrays will give an error. index% must be an integer variable Edited 2021-09-14 20:30 by matherp |
||||
Volhout Guru ![]() Joined: 05/03/2018 Location: NetherlandsPosts: 4836 |
Wow ! I was merely asking a question... And it is already invented and implemented !! Tonight I will immediately implement it. Thanks Peter !!!! PicomiteVGA PETSCII ROBOTS |
||||
disco4now![]() Guru ![]() Joined: 18/12/2014 Location: AustraliaPosts: 969 |
Updated PicoCFunctions.h uSec(a) macro updated as above to match bug fix for uSec function. USERLCDPANEL is now 17 to match latest firmware. #define uSec(a) (void (*)(unsigned long long )) Vector_uSec) (a) #define USERLCDPANEL 17 PicoCFunctions.zip Peter, Could the LCDPANEL USER display ID be moved up a few spots in the next update so it leaves a few spots and does not change when/if a new display is added. uSec() seems to be good now. Regards Gerry Latest F4 Latest H7 FotS |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10041 |
I'll move it to 25 in b18 |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10041 |
PicoMiteV5.07.01b18.zip User display is now #25 (untested) setpin n,intl,myint now allowed on the touch irq pin when GUI functionality is not enabled. If the number of GUI controls is set to something other than 0 then use GUI INTERRUPT. In this case the setpin will error. Additional parameter on PIO INIT PIO INIT MACHINE pio%, statemachine%, clockspeed [,pinctrl] [,execctrl] [,shiftctrl][,startinstruction] The startinstruction parameter tells the PIO which is the first instruction when PIO START is used (was previously always 0) PIO EXECUTE need now only be used when you want to interrupt an existing program. It immediately terminates the currently executing instruction and starts running from the instruction specified |
||||
Page 1 of 3 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |