Here's my-first-task.c as it stands now.
#include "config.h" // include all headers in case a new file
#include "application_lcd.h" // {46} LCD tests
#include "../../hardware/LPC23XX/spi_acc_lpc_AIS226_2.h" // AIS226 accelerometer
extern void fnMyFirstTask(TTASKTABLE *ptrTaskTable)
{
//vars
static int iState = 0;
int y_high = 0;
int y_low = 0;
int y_now = 0;
// init some stuff
GLCD_TEXT_POSITION text_pos;
GLCD_RECT_BLINK rectjah;
// setup some task stuff / initialize code based on task state
if (!iState) {
// LCD PWM to dim.
fnSetLCDContrast();
// print something to LCD
text_pos.ucMode = PAINT_LIGHT;
text_pos.usX = 2;
text_pos.usY = 40;
text_pos.ucFont = (FONT_FIVE_DOT);
// an ack is requested when this has been completely displayed
text_pos.ucMode = (REDRAW | GIVE_ACK);
fnDoLCD_text(&text_pos, "my first task sais hellow");
// print blinking LCD heart beat indicator box
text_pos.usX = 2;
text_pos.usY = 0;
text_pos.ucFont = FONT_NINE_DOT;
rectjah.ucMode = BLINKING_OBJECT;
rectjah.rect_corners.usX_start = 120;
rectjah.rect_corners.usY_start = 120;
rectjah.rect_corners.usX_end = 125;
rectjah.rect_corners.usY_end = 125;
rectjah.blink_half_period = (DELAY_LIMIT)(0.3*SEC);
fnDoLCD_rect(&rectjah);
//config the SPI for the AIS226
fnConfigSPI_AIS226();
// set starting points for min and max indicators
y_high = fnSPI_AIS226(OUTY_L, SPI_READ, 0x00);
y_high = y_high + (fnSPI_AIS226(OUTY_H, SPI_READ, 0x00) << 8);
y_low = y_high;
fnLCD_display_hex(95,100,"high Y",y_high);
fnLCD_display_hex(85,100,"",(y_high >> 8));
// fnLCD_display_hex(85,110,"",(y_low >> 8));
// fnLCD_display_hex(95,110,"low Y",y_low);
iState = 1;
}
// read acceleration and display on screen
//fnLCD_display_hex(95,50,"hex X",fnSPI_AIS226(OUTX_L, SPI_READ, 0x00));
//fnLCD_display_hex(85,50,"",fnSPI_AIS226(OUTX_H, SPI_READ, 0x00));
y_now = fnSPI_AIS226(OUTY_L, SPI_READ, 0x00);
y_now = y_now + (fnSPI_AIS226(OUTY_H, SPI_READ, 0x00) << 8);
if (y_now > y_high) y_high = y_now;
if (y_now < y_low) y_low = y_now;
fnLCD_display_hex(95,60,"high Y",y_high);
fnLCD_display_hex(85,60,"",(y_high >> 8));
fnLCD_display_hex(95,70,"now Y",y_now);
// fnLCD_display_hex(85,70,"",(y_now >> 8));
// fnLCD_display_hex(95,80,"low Y",y_low);
// fnLCD_display_hex(85,80,"",(y_now >> 8));
//fnLCD_display_hex(85,60,"",yh_high);
//fnLCD_display_hex(85,70,"",fnSPI_AIS226(STATUS_REG, SPI_READ, 0x00));
//fnLCD_display_bits(95,50,"PCLKSEL0",*(unsigned long *)0xE01FC1A8 >> 4);// >> 0&0xE0020000);
}
I have modified TaskConfig.h like this
#if defined SUPPORT_LCD
{ "LCD", fnLCD, LARGE_QUE/*MEDIUM_QUE*/, (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO), 0, UTASKER_STOP}, //
#elif defined SUPPORT_GLCD || defined SUPPORT_OLED || defined SUPPORT_TFT || defined GLCD_COLOR // {2}{4}
#ifdef GLCD_COLOR
{ "LCD", fnLCD, LARGE_QUE/*SMALL_QUEUE*/, (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO), 0, UTASKER_ACTIVATE}, // runs immediately
#else
{ "LCD", fnLCD, (LARGE_QUE + 128), (DELAY_LIMIT)(NO_DELAY_RESERVE_MONO), 0, UTASKER_STOP}, // large queue for queuing text
#endif
The above code is grey, but appears to be compiled. Here's spi_acc_lpc_AIS226_2.h
//prototypes
int fnSPI_AIS226(int, int, int);
//defines
#define SET_AIS226_CS_LOW() _CLEARBITS(0, PORT0_BIT6) // assert the CS line of the AIS226
#define SET_AIS226_CS_HIGH() _SETBITS(0, PORT0_BIT6) // negate the CS line of the AIS226
#define WHO_AM_I 0x0F //memory location 0x0F should read as 0x3A
#define STATUS_REG 0x27
#define CTRL_REG1 0x20
#define OUTX_L 0x28
#define OUTX_H 0x29
#define OUTY_L 0x2A
#define OUTY_H 0x2B
#define SPI_READ 0x80 //memory location 0x0F should read as 0x3A
#define SPI_WRITE 0x00 //memory location 0x0F should read as 0x3A
static void fnConfigSPI_AIS226(void)//
{
//pg 436 setup
POWER_UP(PCSSP1); // power up the SPI on SSP port
//clock note, PCLK_SEL0 select PCLK_SPI default is cclk/4, set bits 16:17 (11) for cclk/8
PCLKSEL0 |= PCLK_SSP1_CCLK_8;// set for /8
CONFIGURE_SPI_PINS(); //SET PINSEL0 BITS to make pins SPI
CONFIGURE_CS_LINES(); //FIO0SET and FIO0DIR for software driven CS line
//PINMODE0 |= PINMODE_NO_PULLS_6;//PINMODE_PULLDOWN_6;
//PINMODE0 |= PINMODE_NO_PULLS_7;//PINMODE_PULLDOWN_7;
//PINMODE0 |= PINMODE_NO_PULLS_8;// P0.8 is driven by the slave, so don't drive it here
//PINMODE0 |= PINMODE_NO_PULLS_9;//PINMODE_PULLDOWN_9;
//irq's
//NA verified as off
//other setup
SSPCPSR_X = 16; // set clock prescaler (even prescale 2..254)
SSPCR0_X = (DSS_8_BIT); //| FRS_MICROWIRE); // set 8 bit words
SSPCR1_X = SSP_SSE; // enable
//make sure AIS226 is set to read a value
fnSPI_AIS226(CTRL_REG1, SPI_WRITE, (0xC0 | fnSPI_AIS226(CTRL_REG1, SPI_READ, 0x00)));
}
static void fnLCD_display_bits(int x, int y, const CHAR *LCD_text, unsigned long bits_displayed){
// init some stuff
GLCD_TEXT_POSITION text_pos;// = {PAINT_LIGHT, 2, 0, FONT_NINE_DOT};
// print something to LCD
text_pos.ucMode = PAINT_LIGHT;
text_pos.ucFont = (FONT_FIVE_DOT);
text_pos.usY = y;
text_pos.usX = x;
fnDoLCD_text(&text_pos, LCD_text);
text_pos.usX = x-47;
fnDoLCD_text(&text_pos, " ");//clear display area
text_pos.usX = x-10;
if (bits_displayed & 0x0001) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-15;
if (bits_displayed & 0x0002) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-20;
if (bits_displayed & 0x0004) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-25;
if (bits_displayed & 0x0008) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-32;
if (bits_displayed & 0x0010) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-37;
if (bits_displayed & 0x0020) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-42;
if (bits_displayed & 0x0040) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-47;
if (bits_displayed & 0x0080) fnDoLCD_text(&text_pos, "1");
else fnDoLCD_text(&text_pos, "0");
}
static void fnLCD_display_hex(int x, int y, const CHAR *LCD_text, int hex_displayed){
// init some stuff
GLCD_TEXT_POSITION text_pos;// = {PAINT_LIGHT, 2, 0, FONT_NINE_DOT};
text_pos.ucMode = PAINT_LIGHT;
text_pos.ucFont = (FONT_FIVE_DOT);
text_pos.usY = y;
text_pos.usX = x;
fnDoLCD_text(&text_pos, LCD_text);
text_pos.usX = x-20;
fnDoLCD_text(&text_pos, " ");//clear display area
text_pos.usX = x-10;
if (hex_displayed & 0x1) fnDoLCD_text(&text_pos, "1");
else if (hex_displayed & 0x2) fnDoLCD_text(&text_pos, "2");
else if (hex_displayed & 0x3) fnDoLCD_text(&text_pos, "3");
else if (hex_displayed & 0x4) fnDoLCD_text(&text_pos, "4");
else if (hex_displayed & 0x5) fnDoLCD_text(&text_pos, "5");
else if (hex_displayed & 0x6) fnDoLCD_text(&text_pos, "6");
else if (hex_displayed & 0x7) fnDoLCD_text(&text_pos, "7");
else if (hex_displayed & 0x8) fnDoLCD_text(&text_pos, "8");
else if (hex_displayed & 0x9) fnDoLCD_text(&text_pos, "9");
else if (hex_displayed & 0xA) fnDoLCD_text(&text_pos, "A");
else if (hex_displayed & 0xB) fnDoLCD_text(&text_pos, "B");
else if (hex_displayed & 0xC) fnDoLCD_text(&text_pos, "C");
else if (hex_displayed & 0xD) fnDoLCD_text(&text_pos, "D");
else if (hex_displayed & 0xE) fnDoLCD_text(&text_pos, "E");
else if (hex_displayed & 0xF) fnDoLCD_text(&text_pos, "F");
else fnDoLCD_text(&text_pos, "0");
text_pos.usX = x-15;
if (hex_displayed & 0x10) fnDoLCD_text(&text_pos, "1");
else if (hex_displayed & 0x20) fnDoLCD_text(&text_pos, "2");
else if (hex_displayed & 0x30) fnDoLCD_text(&text_pos, "3");
else if (hex_displayed & 0x40) fnDoLCD_text(&text_pos, "4");
else if (hex_displayed & 0x50) fnDoLCD_text(&text_pos, "5");
else if (hex_displayed & 0x60) fnDoLCD_text(&text_pos, "6");
else if (hex_displayed & 0x70) fnDoLCD_text(&text_pos, "7");
else if (hex_displayed & 0x80) fnDoLCD_text(&text_pos, "8");
else if (hex_displayed & 0x90) fnDoLCD_text(&text_pos, "9");
else if (hex_displayed & 0xA0) fnDoLCD_text(&text_pos, "A");
else if (hex_displayed & 0xB0) fnDoLCD_text(&text_pos, "B");
else if (hex_displayed & 0xC0) fnDoLCD_text(&text_pos, "C");
else if (hex_displayed & 0xD0) fnDoLCD_text(&text_pos, "D");
else if (hex_displayed & 0xE0) fnDoLCD_text(&text_pos, "E");
else if (hex_displayed & 0xF0) fnDoLCD_text(&text_pos, "F");
else fnDoLCD_text(&text_pos, "0");
}
static void fnSetLCDContrast(void){
// configure PWM output for contrast control
TIMER_INTERRUPT_SETUP timer_setup = {0}; // PWM Timer Init Struct
timer_setup.int_type = TIMER_INTERRUPT; // timer setup type
timer_setup.int_priority = 0;
timer_setup.int_handler = 0; // no interrupts used
timer_setup.timer_reference = PWM1; // use PWM module
timer_setup.timer_mode = (TIMER_PWM_6 | PWM_OUTPUT_PORT_1); // use PWM channel 1 on port 1 output location
timer_setup.timer_value = TIMER_US_DELAY(TIMER_FREQUENCY_VALUE(200));// 10000 Hz contrast frequency
timer_setup.pwm_value = _PWM_PERCENT(27,timer_setup.timer_value);//temp_pars->temp_parameters.ucGLCDContrastPWM, timer_setup.timer_value); // contrast as PWM value
fnConfigureInterrupt((void *)&timer_setup);
}
int fnSPI_AIS226(int cmd, int rw, int SPI_data){
unsigned long temp;
int temp2, null;
temp = SSP0CR0; //appears something else uses this SPI reg, so lets save it and restore it when done with this process
SSP0CR0 = (SSP0CR0 & 0xfff0) | 0x07;//clear the lower 4 bits, and set an 8 bit word
SET_AIS226_CS_LOW(); // assert SS low before starting
//FIO0PIN &= 0xffffffbf; // assert SS low before starting
SSPDR_X = (cmd | rw); // send command the 0x80 sets the read vs write bit.
SSPDR_X = SPI_data; // send blank bits to allow clocks for return command
while (!(SSPSR_X & SSP_RNE)){};//first byte is blank
null = SSPDR_X;
while (!(SSPSR_X & SSP_RNE)){};//second byte is the address
temp2 = SSPDR_X;
while (SSPSR_X & (SSP_BSY | SSP_RNE)) {// wait for all transfers to complete and clear rx buffer
null = SSPDR_X; //save it to ulDummy
}
SET_AIS226_CS_HIGH(); // assert SS high after done transmission
//FIO0PIN |= 0x00000040; // assert SS high after done transmission
SSP0CR0 = temp; //return to the normally scheduled program.
return temp2;
}
I changed application_LCD.h like this
case TASK_LCD:
fnRead( PortIDInternal, ucInputMessage, ucInputMessage[MSG_CONTENT_LENGTH]); // read the complete message
if (E_LCD_INITIALISED == ucInputMessage[0]) {
#if !defined SUPPORT_TFT
GLCD_TEXT_POSITION text_pos;// = {PAINT_LIGHT, 2, 0, FONT_NINE_DOT};
text_pos.ucMode = PAINT_LIGHT;
text_pos.usX = 2;
text_pos.usY = 15;
text_pos.ucFont = (FONT_FIVE_DOT);
fnDoLCD_text(&text_pos, "We'll show you how");
text_pos.usY = 40;
text_pos.ucFont = (FONT_FIVE_DOT);
text_pos.ucMode = (REDRAW | GIVE_ACK); // an ack is requested when this has been completely displayed
fnDoLCD_text(&text_pos, "started");
#endif
}
/*else if (E_LCD_READY == ucInputMessage[0]) { // an acknowledgement from the display task (last job has been completed)
blah, blah
}*/
break;
#endif
I know there are bugs in my-first-task.c. Currently it doesn't display the high and low values as expected. They appear, but appear to be incorrect numbers. It seems to ignore the if statement and always runs y_high = y_now. I believe that issue is separate from the display issues. I think I'm just using the logic operator incorrectly.
I believe I have increased the buffer size in the TaskConfig.h. Also my SPI coms send two bytes, then waits for completion of those two. So I believe it should send a max of 2 out of the 8 deep fifo. Is the 8 fifo shared with the LCD's I2C? I have to confess some ignorance about the details of the fifo.