Mercurial > ~darius > hgwebdir.cgi > stm32temp
changeset 8:58d76cf522ff
Split out code into separate files.
author | Daniel O'Connor <darius@dons.net.au> |
---|---|
date | Sat, 04 Feb 2012 13:29:31 +1030 |
parents | 9404b9869c27 |
children | be0a1ac64d97 |
files | BSDmakefile delay.c delay.h flash.c flash.h hw.c hw.h lcd.c lcd.h main.c spi.c spi.h touch.c touch.h |
diffstat | 14 files changed, 699 insertions(+), 553 deletions(-) [+] |
line wrap: on
line diff
--- a/BSDmakefile Sun Jan 22 17:10:51 2012 +1030 +++ b/BSDmakefile Sat Feb 04 13:29:31 2012 +1030 @@ -2,12 +2,17 @@ SRCS= comm.c \ core_cm3.c \ + delay.c \ + flash.c \ + hw.c \ lcd.c \ main.c \ misc.c \ + spi.c \ startup_stm32f10x_md_mthomas.c \ syscalls.c \ - system_stm32f10x.c + system_stm32f10x.c \ + touch.c STM32LIBS= usart gpio rcc rtc pwr bkp fsmc spi tim
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/delay.c Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,14 @@ +#include <stdint.h> +#include "stm32f10x.h" +#include "delay.h" + +/* This is a bit rough and ready */ +void +delay(__IO uint32_t nCount) { + __IO uint32_t i; + + for(; nCount != 0; nCount--) + for (i = 0; i < 3900; i++) + ; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/delay.h Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,3 @@ +void delay(__IO uint32_t nCount); + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flash.c Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,57 @@ +#include <stdint.h> + +#include "stm32f10x.h" +#include "spi.h" +#include "flash.h" + +#define FL_SELECT() GPIO_ResetBits(GPIOA, GPIO_Pin_4) +#define FL_DESELECT() GPIO_SetBits(GPIOA, GPIO_Pin_4) + +uint16_t +flashreadid(void) { + uint8_t fac, dev; + + FL_SELECT(); /* Select device */ + + SPI_WriteByte(FL_RDID); /* Send command */ + SPI_WriteByte(0x00); /* Send address cycles (ID data starts at 0) */ + SPI_WriteByte(0x00); + SPI_WriteByte(0x00); + fac = SPI_WriteByte(0x00); /* Read ID */ + dev = SPI_WriteByte(0x00); + + FL_DESELECT(); /* De-select device */ + + return fac << 8 | dev; +} + +uint8_t +flashreadstatus(void) { + uint8_t status; + + FL_SELECT(); /* Select device */ + + SPI_WriteByte(FL_RDSR); /* Send command */ + SPI_WriteByte(0x00); /* Send dummy byte for address cycle */ + status = SPI_WriteByte(0x00); /* Read status */ + + FL_DESELECT(); /* De-select device */ + + return status; +} + +void +flashwritestatus(uint8_t status) { + /* Enable status write */ + FL_SELECT(); /* Select device */ + SPI_WriteByte(FL_EWSR); /* Send command */ + SPI_WriteByte(0x00); /* Send data byte */ + FL_DESELECT(); + + /* Actually write status */ + FL_SELECT(); /* Re-select device for new command */ + SPI_WriteByte(FL_WRSR); /* Send command */ + SPI_WriteByte(status); /* Send data byte */ + FL_DESELECT(); /* De-select device */ +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flash.h Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,29 @@ +uint16_t flashreadid(void); +uint8_t flashreadstatus(void); +void flashwritestatus(uint8_t status); +void flashwritectl(int enable); + +#define FL_BP0 (1<<2) +#define FL_BP1 (1<<3) +#define FL_BP2 (1<<4) +#define FL_BP3 (1<<5) +#define FL_BPL (1<<7) + +#define FL_READ 0x03 +#define FL_HSREAD 0x0b +#define FL_32KERASE 0x52 +#define FL_64KERASE 0xd8 +#define FL_CHIPERASE 0x60 +#define FL_BYTEPROG 0x02 +#define FL_AAIWP 0xad +#define FL_RDSR 0x05 +#define FL_EWSR 0x50 +#define FL_WRSR 0x01 +#define FL_WREN 0x06 +#define FL_WRDI 0x04 +#define FL_RDID 0x90 +#define FL_JEDECID 0x9f +#define FL_EBSY 0x70 +#define FL_DBSY 0x80 + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hw.c Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,263 @@ +#include <stdint.h> +#include "stm32f10x.h" +#include "lcd.h" + +static void hw_port_cfg(void); + + +void hw_init(void) { + hw_port_cfg(); + lcd_init(); + lcd_setpwm(1000); +} + +static void +hw_port_cfg(void) { + GPIO_InitTypeDef GPIO_InitStructure; + USART_InitTypeDef USART_InitStructure; + SPI_InitTypeDef SPI_InitStructure; + FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; + FSMC_NORSRAMTimingInitTypeDef p; + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + + /* RTC stuff */ + /* Enable PWR and BKP clocks */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); + + /* Allow access to BKP Domain */ + PWR_BackupAccessCmd(ENABLE); + + /* Reset Backup Domain + * + * This resets the RTC etc back to 0 so probably only useful under user command + BKP_DeInit(); + */ + + /* Enable Low Speed External clock */ + RCC_LSEConfig(RCC_LSE_ON); + + /* Wait till LSE is ready */ + while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) + ; + + /* Select LSE as RTC Clock Source */ + RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); + + /* Enable RTC Clock */ + RCC_RTCCLKCmd(ENABLE); + + /* Wait for RTC registers synchronization */ + RTC_WaitForSynchro(); + + /* Wait until last write operation on RTC registers has finished */ + RTC_WaitForLastTask(); + + /* Wait until last write operation on RTC registers has finished */ + RTC_WaitForLastTask(); + + /* Set RTC prescaler: set RTC period to 1sec */ + RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */ + + /* Wait until last write operation on RTC registers has finished */ + RTC_WaitForLastTask(); + + /* Clock setup */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); + + /* Port configuration */ + /* Configure USART1 TX (PA.09) as alternate function push-pull */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /* Configure USART1 RX (PA.10) as input floating */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /* Enable GPIOB clock */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); + + /* Configure PB5 as output push-pull for LED */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + /* Configure PB15 as input pull-up push-pull for push button */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + /* USART configuration */ + /* USART1 - 115200 8n1, no flow control TX & RX enabled */ + USART_InitStructure.USART_BaudRate = 115200; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; + USART_Init(USART1, &USART_InitStructure); + + /* Enable interrupts on receive data */ + USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); + + /* Enable USART */ + USART_Cmd(USART1, ENABLE); + + /* Enable FSMC clock */ + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); + + /* Enable alternate function IO clock */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); + + /* Enable GPIOD clock */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); + + /* Enable GPIOD clock */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); + + /* Configures LCD Control lines (FSMC Pins) in alternate function Push-Pull mode. + * + * PD0(D2), PD1(D3), PD4(NOE), PD5(NWE), PD7(NE1/CS), PD8(D13), PD9(D14), + * PD10(D15), PD11(A16/RS) PD14(D0), PD15(D1) + */ + GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | + GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | + GPIO_Pin_14 | GPIO_Pin_15); + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + /* PE7(D4), PE8(D5), PE9(D6), PE10(D7), PE11(D8), PE12(D9), PE13(D10), + * PE14(D11), PE15(D12) + */ + GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | + GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | + GPIO_Pin_15); + GPIO_Init(GPIOE, &GPIO_InitStructure); + + /* Configure backlight control (PD13/FSMC_A18 remapped to TIM4_CH2) */ + /* Enable TIM4 clock */ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); + + /* Enable timer function + * Note source clock is SYSCLK / 2 = 36MHz + */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOD, &GPIO_InitStructure); + + /* Remap TIM4_CH2 to PD13 */ + GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); + + /* Reset TIM4 */ + TIM_DeInit(TIM4); + + /* Time Base configuration */ + TIM_TimeBaseStructure.TIM_Period = 999; + TIM_TimeBaseStructure.TIM_Prescaler = 0; + TIM_TimeBaseStructure.TIM_ClockDivision = 0; + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; + + TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); + + /* Enable timer */ + TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); + TIM_ARRPreloadConfig(TIM4, ENABLE); + TIM_Cmd(TIM4, ENABLE); + + /* Configure reset pin (PE1) as GPIO out PP */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOE, &GPIO_InitStructure); + + /* Configures the Parallel interface (FSMC) for LCD (Parallel mode) */ + /* Timing configuration */ + p.FSMC_AddressSetupTime = 5; + p.FSMC_AddressHoldTime = 5; + p.FSMC_DataSetupTime = 5; + p.FSMC_BusTurnAroundDuration = 0; + p.FSMC_CLKDivision = 0; + p.FSMC_DataLatency = 0; + p.FSMC_AccessMode = FSMC_AccessMode_A; + + /* FSMC_Bank1_NORSRAM1 configured as follows: + - Data/Address MUX = Disable + - Memory Type = SRAM + - Data Width = 16bit + - Write Operation = Enable + - Extended Mode = Disable + - Asynchronous Wait = Disable */ + FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; + FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; + FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; + FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; + FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; + FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; + FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); + + /* Enable FSMC_Bank1_NORSRAM1 */ + FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); + + /* Configure touch screen controller + * + * Connected to SPI1 which is shared with the AT45DB161D. + * + * The touch screen is selected with PB7. + * The flash chip is selected with PA4. + */ + + /* Enable SPI1 clock */ + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); + + /* Configure MOSI, MISO and SCLK as alternate function PP */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /* Configure flash chip select pin (PA4) as GPIO out PP */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOA, &GPIO_InitStructure); + + /* Configure touch chip select pin (PB7) as GPIO out PP */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; + GPIO_Init(GPIOB, &GPIO_InitStructure); + + /* De-select touch & flash */ + GPIO_SetBits(GPIOA, GPIO_Pin_4); + GPIO_SetBits(GPIOB, GPIO_Pin_7); + + /* SPI1 Config */ + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + SPI_Init(SPI1, &SPI_InitStructure); + + /* SPI1 enable */ + SPI_Cmd(SPI1, ENABLE); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hw.h Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,2 @@ +void hw_init(void); +
--- a/lcd.c Sun Jan 22 17:10:51 2012 +1030 +++ b/lcd.c Sat Feb 04 13:29:31 2012 +1030 @@ -56,28 +56,28 @@ */ #include <stdio.h> +#include <stdint.h> #include "stm32f10x.h" #include "lcd.h" - -static void LCD_Doinit(void); +#include "delay.h" #define Bank1_LCD_C ((uint32_t)0x60000000) /* Register Address */ #define Bank1_LCD_D ((uint32_t)0x60020000) /* Data Address */ void -LCD_WR_Reg(uint16_t index, uint16_t val) { +lcd_wr_reg(uint16_t index, uint16_t val) { *(__IO uint16_t *)(Bank1_LCD_C) = index; *(__IO uint16_t *)(Bank1_LCD_D) = val; } uint16_t -LCD_RD_Reg(uint16_t index) { +lcd_rd_reg(uint16_t index) { *(__IO uint16_t *)(Bank1_LCD_C) = index; return(*(__IO uint16_t *)(Bank1_LCD_D)); } uint16_t -LCD_RD_Data(int first) { +lcd_rd_data(int first) { uint16_t a = 0; if (first) a = *(__IO uint16_t *) (Bank1_LCD_D); /* Dummy */ @@ -87,313 +87,17 @@ } void -LCD_WR_StartData(uint16_t x, uint16_t y) { - LCD_WR_Reg(0x20, x); - LCD_WR_Reg(0x21, y); +lcd_wr_startdata(uint16_t x, uint16_t y) { + lcd_wr_reg(0x20, x); + lcd_wr_reg(0x21, y); *(__IO uint16_t *)(Bank1_LCD_C) = 0x22; /* Start GRAM write */ } void -LCD_WR_Data(uint16_t val) { +lcd_wr_data(uint16_t val) { *(__IO uint16_t *)(Bank1_LCD_D) = val; } -/* This is a bit rough and ready */ -void -Delay(__IO uint32_t nCount) { - __IO uint32_t i; - - for(; nCount != 0; nCount--) - for (i = 0; i < 3900; i++) - ; -} - -uint8_t -SPI_WriteByte(uint8_t out) { - uint8_t in = 0; - - /* Wait until the transmit buffer is empty */ - while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET) - ; - - /* Send the byte */ - SPI_I2S_SendData(SPI1, out); - - /* Wait until a data is received */ - while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET) - ; - - /* Get the received data */ - in = SPI_I2S_ReceiveData(SPI1); - - /* Return the shifted data */ - return (in); -} - -#define TP_SELECT() GPIO_ResetBits(GPIOB, GPIO_Pin_7) -#define TP_DESELECT() GPIO_SetBits(GPIOB, GPIO_Pin_7) -uint16_t -TPRead(uint8_t type) { - uint16_t x = 0; - - /* Select device */ - TP_SELECT(); - - /* Do conversion */ - Delay(10); - SPI_WriteByte(type); - - /* Read result */ - Delay(10); - x = SPI_WriteByte(0x00); - x <<= 8; - x |= SPI_WriteByte(0x00); - Delay(10); - - /* De-select device */ - TP_DESELECT(); - - /* Right justify 12 bit result */ - x = x >> 3; - return (x); -} - -#define FL_SELECT() GPIO_ResetBits(GPIOA, GPIO_Pin_4) -#define FL_DESELECT() GPIO_SetBits(GPIOA, GPIO_Pin_4) - -#define FL_READ 0x03 -#define FL_HSREAD 0x0b -#define FL_32KERASE 0x52 -#define FL_64KERASE 0xd8 -#define FL_CHIPERASE 0x60 -#define FL_BYTEPROG 0x02 -#define FL_AAIWP 0xad -#define FL_RDSR 0x05 -#define FL_EWSR 0x50 -#define FL_WRSR 0x01 -#define FL_WREN 0x06 -#define FL_WRDI 0x04 -#define FL_RDID 0x90 -#define FL_JEDECID 0x9f -#define FL_EBSY 0x70 -#define FL_DBSY 0x80 - -uint16_t -FlashReadID(void) { - uint8_t fac, dev; - - FL_SELECT(); /* Select device */ - - SPI_WriteByte(FL_RDID); /* Send command */ - SPI_WriteByte(0x00); /* Send address cycles (ID data starts at 0) */ - SPI_WriteByte(0x00); - SPI_WriteByte(0x00); - fac = SPI_WriteByte(0x00); /* Read ID */ - dev = SPI_WriteByte(0x00); - - FL_DESELECT(); /* De-select device */ - - return fac << 8 | dev; -} - -uint8_t -FlashReadStatus(void) { - uint8_t status; - - FL_SELECT(); /* Select device */ - - SPI_WriteByte(FL_RDSR); /* Send command */ - SPI_WriteByte(0x00); /* Send dummy byte for address cycle */ - status = SPI_WriteByte(0x00); /* Read status */ - - FL_DESELECT(); /* De-select device */ - - return status; -} - -void -FlashWriteStatus(uint8_t status) { - /* Enable status write */ - FL_SELECT(); /* Select device */ - SPI_WriteByte(FL_EWSR); /* Send command */ - SPI_WriteByte(0x00); /* Send data byte */ - FL_DESELECT(); - - /* Actually write status */ - FL_SELECT(); /* Re-select device for new command */ - SPI_WriteByte(FL_WRSR); /* Send command */ - SPI_WriteByte(status); /* Send data byte */ - FL_DESELECT(); /* De-select device */ -} - -void -LCD_init(void) { - GPIO_InitTypeDef GPIO_InitStructure; - SPI_InitTypeDef SPI_InitStructure; - FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure; - FSMC_NORSRAMTimingInitTypeDef p; - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - - /* Enable FSMC clock */ - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE); - - /* Enable alternate function IO clock */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); - - /* Enable GPIOD clock */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); - - /* Enable GPIOD clock */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); - - /* Configures LCD Control lines (FSMC Pins) in alternate function Push-Pull mode. - * - * PD0(D2), PD1(D3), PD4(NOE), PD5(NWE), PD7(NE1/CS), PD8(D13), PD9(D14), - * PD10(D15), PD11(A16/RS) PD14(D0), PD15(D1) - */ - GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | - GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | - GPIO_Pin_14 | GPIO_Pin_15); - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOD, &GPIO_InitStructure); - - /* PE7(D4), PE8(D5), PE9(D6), PE10(D7), PE11(D8), PE12(D9), PE13(D10), - * PE14(D11), PE15(D12) - */ - GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | - GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | - GPIO_Pin_15); - GPIO_Init(GPIOE, &GPIO_InitStructure); - - /* Configure backlight control (PD13/FSMC_A18 remapped to TIM4_CH2) */ - /* Enable TIM4 clock */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); - - /* Enable timer function - * Note source clock is SYSCLK / 2 = 36MHz - */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOD, &GPIO_InitStructure); - - /* Remap TIM4_CH2 to PD13 */ - GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); - - /* Reset TIM4 */ - TIM_DeInit(TIM4); - - /* Time Base configuration */ - TIM_TimeBaseStructure.TIM_Period = 999; - TIM_TimeBaseStructure.TIM_Prescaler = 0; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Down; - - TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); - - /* Init to full brightness */ - lcd_setpwm(1000); - - /* Enable timer */ - TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); - TIM_ARRPreloadConfig(TIM4, ENABLE); - TIM_Cmd(TIM4, ENABLE); - - /* Configure reset pin (PE1) as GPIO out PP */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOE, &GPIO_InitStructure); - - /* Configures the Parallel interface (FSMC) for LCD (Parallel mode) */ - /* Timing configuration */ - p.FSMC_AddressSetupTime = 5; - p.FSMC_AddressHoldTime = 5; - p.FSMC_DataSetupTime = 5; - p.FSMC_BusTurnAroundDuration = 0; - p.FSMC_CLKDivision = 0; - p.FSMC_DataLatency = 0; - p.FSMC_AccessMode = FSMC_AccessMode_A; - - /* FSMC_Bank1_NORSRAM1 configured as follows: - - Data/Address MUX = Disable - - Memory Type = SRAM - - Data Width = 16bit - - Write Operation = Enable - - Extended Mode = Disable - - Asynchronous Wait = Disable */ - FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1; - FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; - FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; - FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; - FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; - FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; - FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; - FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; - FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; - FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; - FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); - - /* Enable FSMC_Bank1_NORSRAM1 */ - FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); - - /* Configure touch screen controller - * - * Connected to SPI1 which is shared with the AT45DB161D. - * - * The touch screen is selected with PB7. - * The flash chip is selected with PA4. - */ - - /* Enable SPI1 clock */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); - - /* Configure MOSI, MISO and SCLK as alternate function PP */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* Configure flash chip select pin (PA4) as GPIO out PP */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* Configure touch chip select pin (PB7) as GPIO out PP */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - /* De-select touch & flash */ - GPIO_SetBits(GPIOA, GPIO_Pin_4); - GPIO_SetBits(GPIOB, GPIO_Pin_7); - - /* SPI1 Config */ - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - SPI_InitStructure.SPI_Mode = SPI_Mode_Master; - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; - SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; - SPI_InitStructure.SPI_CRCPolynomial = 7; - SPI_Init(SPI1, &SPI_InitStructure); - - /* SPI1 enable */ - SPI_Cmd(SPI1, ENABLE); - - LCD_Doinit(); -} - void lcd_setpwm(uint16_t val) { TIM_OCInitTypeDef TIM_OCInitStructure; @@ -408,127 +112,206 @@ } -static void -LCD_Doinit(void) { +void +lcd_init(void) { uint16_t id; /* Initialise LCD panel */ /* Pull reset pin low */ - Delay(1); + delay(1); GPIO_ResetBits(GPIOE, GPIO_Pin_1); - Delay(10); + delay(10); GPIO_SetBits(GPIOE, GPIO_Pin_1); - Delay(50); + delay(50); - id = LCD_RD_Reg(0x00); + id = lcd_rd_reg(0x00); if (id != 0x9325) { printf("LCD ID doesn't match, expected 0x9325 got 0x%x\r\n", id); return; } printf("LCD ID matches\r\n"); - LCD_WR_Reg(0x00e3, 0x3008); /* Set internal timing (not documented) */ - LCD_WR_Reg(0x00e7, 0x0012); /* Set internal timing (not documented) */ - LCD_WR_Reg(0x00ef, 0x1231); /* Set internal timing (not documented) */ - LCD_WR_Reg(0x0000, 0x0001); /* Start Oscillation */ - Delay(50); - LCD_WR_Reg(0x0001, 0x0100); /* set SS (S720 -> S1) */ - LCD_WR_Reg(0x0002, 0x0700); /* set line inversion (B/C + EOR) */ - LCD_WR_Reg(0x0004, 0x0000); /* no resizing */ - LCD_WR_Reg(0x0008, 0x0202); /* set the back porch and front porch (2 lines each) */ - LCD_WR_Reg(0x0009, 0x0000); /* set non-display area refresh cycle ISC[3:0] */ - LCD_WR_Reg(0x000a, 0x0000); /* FMARK function */ + lcd_wr_reg(0x00e3, 0x3008); /* Set internal timing (not documented) */ + lcd_wr_reg(0x00e7, 0x0012); /* Set internal timing (not documented) */ + lcd_wr_reg(0x00ef, 0x1231); /* Set internal timing (not documented) */ + lcd_wr_reg(0x0000, 0x0001); /* Start Oscillation */ + delay(50); + lcd_wr_reg(0x0001, 0x0100); /* set SS (S720 -> S1) */ + lcd_wr_reg(0x0002, 0x0700); /* set line inversion (B/C + EOR) */ + lcd_wr_reg(0x0004, 0x0000); /* no resizing */ + lcd_wr_reg(0x0008, 0x0202); /* set the back porch and front porch (2 lines each) */ + lcd_wr_reg(0x0009, 0x0000); /* set non-display area refresh cycle ISC[3:0] */ + lcd_wr_reg(0x000a, 0x0000); /* FMARK function */ - LCD_WR_Reg(0x000c, 0x0000); /* RGB ctl - Internal clock, 18bit interface */ - LCD_WR_Reg(0x000d, 0x0000); /* Frame marker Position */ - LCD_WR_Reg(0x000f, 0x0000); /* RGB interface polarity */ + lcd_wr_reg(0x000c, 0x0000); /* RGB ctl - Internal clock, 18bit interface */ + lcd_wr_reg(0x000d, 0x0000); /* Frame marker Position */ + lcd_wr_reg(0x000f, 0x0000); /* RGB interface polarity */ /* Power On sequence */ - LCD_WR_Reg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ - LCD_WR_Reg(0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ - LCD_WR_Reg(0x0012, 0x0000); /* VREG1OUT voltage */ - LCD_WR_Reg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ - Delay(200); /* Dis-charge capacitor power voltage */ - LCD_WR_Reg(0x0010, 0x1690); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ - LCD_WR_Reg(0x0011, 0x0227); /* R11h = 0x0221 at VCI = 3.3V, DC1[2:0], DC0[2:0], VC[2:0] */ - Delay(50); /* Delay 50ms */ - LCD_WR_Reg(0x0012, 0x001c); /* External reference voltage= Vci; */ - Delay(50); /* Delay 50ms */ - LCD_WR_Reg(0x0013, 0x1800); /* R13 = 1200 when R12 = 009D; VDV[4:0] for VCOM amplitude */ - LCD_WR_Reg(0x0029, 0x001c); /* R29 = 000C when R12 = 009D; VCM[5:0] for VCOMH */ - LCD_WR_Reg(0x002b, 0x000d); /* Frame Rate = 91Hz */ - Delay(50); /* Delay 50ms */ + lcd_wr_reg(0x0010, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ + lcd_wr_reg(0x0011, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ + lcd_wr_reg(0x0012, 0x0000); /* VREG1OUT voltage */ + lcd_wr_reg(0x0013, 0x0000); /* VDV[4:0] for VCOM amplitude */ + delay(200); /* Dis-charge capacitor power voltage */ + lcd_wr_reg(0x0010, 0x1690); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ + lcd_wr_reg(0x0011, 0x0227); /* R11h = 0x0221 at VCI = 3.3V, DC1[2:0], DC0[2:0], VC[2:0] */ + delay(50); /* delay 50ms */ + lcd_wr_reg(0x0012, 0x001c); /* External reference voltage= Vci; */ + delay(50); /* delay 50ms */ + lcd_wr_reg(0x0013, 0x1800); /* R13 = 1200 when R12 = 009D; VDV[4:0] for VCOM amplitude */ + lcd_wr_reg(0x0029, 0x001c); /* R29 = 000C when R12 = 009D; VCM[5:0] for VCOMH */ + lcd_wr_reg(0x002b, 0x000d); /* Frame Rate = 91Hz */ + delay(50); /* delay 50ms */ /* Set GRAM area */ - LCD_WR_Reg(0x0050, 0x0000); /* Horizontal GRAM Start Address */ - LCD_WR_Reg(0x0051, 0x00ef); /* Horizontal GRAM End Address */ - LCD_WR_Reg(0x0052, 0x0000); /* Vertical GRAM Start Address */ - LCD_WR_Reg(0x0053, 0x013f); /* Vertical GRAM Start Address */ + lcd_wr_reg(0x0050, 0x0000); /* Horizontal GRAM Start Address */ + lcd_wr_reg(0x0051, 0x00ef); /* Horizontal GRAM End Address */ + lcd_wr_reg(0x0052, 0x0000); /* Vertical GRAM Start Address */ + lcd_wr_reg(0x0053, 0x013f); /* Vertical GRAM Start Address */ - LCD_WR_Reg(0x0060, 0xa700); /* Gate Scan Line, drive G320 -> G1 */ - LCD_WR_Reg(0x0061, 0x0003); /* VLE & REV */ - LCD_WR_Reg(0x006a, 0x0000); /* set scrolling line */ + lcd_wr_reg(0x0060, 0xa700); /* Gate Scan Line, drive G320 -> G1 */ + lcd_wr_reg(0x0061, 0x0003); /* VLE & REV */ + lcd_wr_reg(0x006a, 0x0000); /* set scrolling line */ /* Partial Display Control */ - LCD_WR_Reg(0x0080, 0x0000); /* Image 1 */ - LCD_WR_Reg(0x0081, 0x0000); - LCD_WR_Reg(0x0082, 0x0000); - LCD_WR_Reg(0x0083, 0x0000); /* Image 2 */ - LCD_WR_Reg(0x0084, 0x0000); - LCD_WR_Reg(0x0085, 0x0000); + lcd_wr_reg(0x0080, 0x0000); /* Image 1 */ + lcd_wr_reg(0x0081, 0x0000); + lcd_wr_reg(0x0082, 0x0000); + lcd_wr_reg(0x0083, 0x0000); /* Image 2 */ + lcd_wr_reg(0x0084, 0x0000); + lcd_wr_reg(0x0085, 0x0000); /* Panel Control */ - LCD_WR_Reg(0x0090, 0x0010); - LCD_WR_Reg(0x0092, 0x0000); - LCD_WR_Reg(0x0093, 0x0003); - LCD_WR_Reg(0x0095, 0x0110); - LCD_WR_Reg(0x0097, 0x0000); /* Undocumented */ - LCD_WR_Reg(0x0098, 0x0000); /* Undocumented */ + lcd_wr_reg(0x0090, 0x0010); + lcd_wr_reg(0x0092, 0x0000); + lcd_wr_reg(0x0093, 0x0003); + lcd_wr_reg(0x0095, 0x0110); + lcd_wr_reg(0x0097, 0x0000); /* Undocumented */ + lcd_wr_reg(0x0098, 0x0000); /* Undocumented */ - LCD_WR_Reg(0x0007, 0x0133); /* Display on, 262k colour mode (vs 8) */ + lcd_wr_reg(0x0007, 0x0133); /* Display on, 262k colour mode (vs 8) */ - LCD_WR_Reg(0x0003, 0x1030); /* set GRAM write direction and enable BGR, 64K colours, 1 transfers/pixel. */ + lcd_wr_reg(0x0003, 0x1030); /* set GRAM write direction and enable BGR, 64K colours, 1 transfers/pixel. */ /* Adjust the Gamma Curve */ - LCD_WR_Reg(0x0030, 0x0006); - LCD_WR_Reg(0x0031, 0x0101); - LCD_WR_Reg(0x0032, 0x0003); - LCD_WR_Reg(0x0035, 0x0106); - LCD_WR_Reg(0x0036, 0x0b02); - LCD_WR_Reg(0x0037, 0x0302); - LCD_WR_Reg(0x0038, 0x0707); - LCD_WR_Reg(0x0039, 0x0007); - LCD_WR_Reg(0x003c, 0x0600); - LCD_WR_Reg(0x003d, 0x020b); + lcd_wr_reg(0x0030, 0x0006); + lcd_wr_reg(0x0031, 0x0101); + lcd_wr_reg(0x0032, 0x0003); + lcd_wr_reg(0x0035, 0x0106); + lcd_wr_reg(0x0036, 0x0b02); + lcd_wr_reg(0x0037, 0x0302); + lcd_wr_reg(0x0038, 0x0707); + lcd_wr_reg(0x0039, 0x0007); + lcd_wr_reg(0x003c, 0x0600); + lcd_wr_reg(0x003d, 0x020b); fputs("Testing\r\n", stdout); - LCD_WR_StartData(0, 0); - LCD_WR_Data(0xa5a5); - LCD_WR_Data(0x5a5a); - LCD_WR_StartData(0, 0); - if ((id = LCD_RD_Data(1)) != 0xa5a5) + lcd_wr_startdata(0, 0); + lcd_wr_data(0xa5a5); + lcd_wr_data(0x5a5a); + lcd_wr_startdata(0, 0); + if ((id = lcd_rd_data(1)) != 0xa5a5) printf("Expected 0xa5a5 got 0x%04x\r\n", id); - if ((id = LCD_RD_Data(0)) != 0x5a5a) + if ((id = lcd_rd_data(0)) != 0x5a5a) printf("Expected 0x5a5a got 0x%04x\r\n", id); fputs("Filling\r\n", stdout); /* Fill panel */ - LCD_WR_StartData(0, 0); - -#define RGB24_565(R, G, B) (((((R) >> 3) & 0x1f) << 11) | ((((G) >> 2) & 0x3f) << 5) | (((B) >> 3) & 0x1f)) + lcd_wr_startdata(0, 0); for (int x = 0; x < 320; x++) { for (int y = 0; y < 240; y++) { if (((x / 5) % 3) == 0) - LCD_WR_Data(RGB24_565(255, 0, 0)); + lcd_wr_data(LCD_RED); else if (((x / 5) % 3) == 1) - LCD_WR_Data(RGB24_565(0, 255, 0)); + lcd_wr_data(LCD_GREEN); else - LCD_WR_Data(RGB24_565(0, 0, 255)); + lcd_wr_data(LCD_BLUE); } } + lcd_circle(50, 50, 20, LCD_BLACK); + +} + +void +lcd_pixel(uint16_t x, uint16_t y, uint16_t colour) { + if (x > LCD_HEIGHT || y > LCD_WIDTH) + return; + + lcd_wr_startdata(x, y); + lcd_wr_data(colour); } +/* + * Draw a circle + * From http://en.wikipedia.org/wiki/Midpoint_circle_algorithm + */ +void +lcd_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t colour) { + int16_t f; + uint16_t ddF_x, ddF_y, x, y; + + f = 1 - radius; + ddF_x = 1; + ddF_y = -2 * radius; + x = 0; + y = radius; + + lcd_pixel(x0, y0 + radius, colour); + lcd_pixel(x0, y0 - radius, colour); + lcd_pixel(x0 + radius, y0, colour); + lcd_pixel(x0 - radius, y0, colour); + + while(x < y) { + // ddF_x == 2 * x + 1; + // ddF_y == -2 * y; + // f == x*x + y*y - radius*radius + 2*x - y + 1; + if(f >= 0) { + y--; + ddF_y += 2; + f += ddF_y; + } + x++; + ddF_x += 2; + f += ddF_x; + lcd_pixel(x0 + x, y0 + y, colour); + lcd_pixel(x0 - x, y0 + y, colour); + lcd_pixel(x0 + x, y0 - y, colour); + lcd_pixel(x0 - x, y0 - y, colour); + lcd_pixel(x0 + y, y0 + x, colour); + lcd_pixel(x0 - y, y0 + x, colour); + lcd_pixel(x0 + y, y0 - x, colour); + lcd_pixel(x0 - y, y0 - x, colour); + } +} + + +/* + * Draw a line + * From http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm + */ +void +lcd_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t colour) { + uint16_t dx, dy, d, x, y; + + dx = x1 - x0; + dy = y1 - y0; + + d = 2 * dy - dx; + lcd_pixel(x0, y0, colour); + y = y0; + + for (x = x0 + 1; x <= x1; x++) { + if (d > 0) { + y++; + lcd_pixel(x, y, colour); + d += 2 * dy - 2 * dx; + } else { + lcd_pixel(x, y, colour); + d += 2 * dy; + } + } +}
--- a/lcd.h Sun Jan 22 17:10:51 2012 +1030 +++ b/lcd.h Sat Feb 04 13:29:31 2012 +1030 @@ -1,57 +1,20 @@ -#ifndef LCD_H_ -#define LCD_H_ - -void LCD_init(void); -void LCD_WR_Reg(uint16_t index, uint16_t val); -uint16_t LCD_RD_Reg(uint16_t index); -uint16_t LCD_RD_Data(int first); -void LCD_WR_Data(uint16_t val); -void LCD_WR_StartData(uint16_t x, uint16_t y); -void Delay(__IO uint32_t nCount); - -/* Touch controller (TSC2046N) defines */ -/* Mode/channel select defines */ -#define TP_READ_SEL(chan, mode, ref, pd) (0x80 | (((chan) & 0x07) << 4) | (((mode) & 0x01) << 3) | (((ref) & 0x01) << 2) | ((pd) & 0x03)) - -/* Channel select */ -#define TP_CHAN_TEMP0 0 -#define TP_CHAN_Y 1 -#define TP_CHAN_VBAT 2 -#define TP_CHAN_Z1 3 -#define TP_CHAN_Z2 4 -#define TP_CHAN_X 5 -#define TP_CHAN_AUX 6 -#define TP_CHAN_TEMP1 7 - -/* Mode select */ -#define TP_MODE_12 0 -#define TP_MODE_8 1 +void lcd_init(void); +void lcd_wr_reg(uint16_t index, uint16_t val); +uint16_t lcd_rd_reg(uint16_t index); +uint16_t lcd_rd_data(int first); +void lcd_wr_data(uint16_t val); +void lcd_wr_startdata(uint16_t x, uint16_t y); +void lcd_setpwm(uint16_t val); +void lcd_pixel(uint16_t x, uint16_t y, uint16_t colour); +void lcd_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t colour); +void lcd_line(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t colour); -/* Reference type */ -#define TP_REF_DIFF 0 -#define TP_REF_SER 1 - -/* Power down mode */ -#define TP_PD_AUTO 0 -#define TP_PD_REF_OFF 1 -#define TP_PD_REF_ON 2 -#define TP_PD_ON 3 - -uint16_t TPRead(uint8_t type); +#define LCD_HEIGHT 240 +#define LCD_WIDTH 320 -uint16_t FlashReadID(void); -uint8_t FlashReadStatus(void); - -#define FL_BP0 (1<<2) -#define FL_BP1 (1<<3) -#define FL_BP2 (1<<4) -#define FL_BP3 (1<<5) -#define FL_BPL (1<<7) -void FlashWriteStatus(uint8_t status); - -void FlashWriteCtl(int enable); - -void lcd_setpwm(uint16_t val); - -#endif - +#define RGB24_565(R, G, B) (((((R) >> 3) & 0x1f) << 11) | ((((G) >> 2) & 0x3f) << 5) | (((B) >> 3) & 0x1f)) +#define LCD_WHITE RGB24_565(255, 255, 255) +#define LCD_BLACK RGB24_565(0, 0, 0) +#define LCD_RED RGB24_565(255, 0, 0) +#define LCD_GREEN RGB24_565(0, 255, 0) +#define LCD_BLUE RGB24_565(0, 0, 255)
--- a/main.c Sun Jan 22 17:10:51 2012 +1030 +++ b/main.c Sat Feb 04 13:29:31 2012 +1030 @@ -8,9 +8,14 @@ #include <stdlib.h> #include "stm32f10x.h" + +#include "comm.h" +#include "delay.h" +#include "flash.h" +#include "hw.h" #include "lcd.h" #include "main.h" -#include "comm.h" +#include "touch.h" typedef struct { char buf[40]; @@ -18,7 +23,6 @@ uint8_t len; } consbuf_t; -void Setup_HW(void); void NVIC_Configuration(void); @@ -105,8 +109,8 @@ cmd.state = cmd.len = 0; - /* Setup USART etc */ - Setup_HW(); + /* Init hardware - configure IO ports and external peripherals */ + hw_init(); /* NVIC configuration */ NVIC_Configuration(); @@ -119,9 +123,6 @@ ; } - /* Init LCD panel */ - LCD_init(); - /* Set stdout to unbuffered */ setvbuf(stdout, NULL, _IONBF, 0); @@ -148,16 +149,10 @@ } else if (!strncmp("read", cmd.buf, 4)) { printf("PB5 = %d\r\n", GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15)); } else if (!strncmp("touch", cmd.buf, 5)) { + uint16_t x, y, z1, z2; + float t, t2; for (int i = 0; i < 10; i++) { - uint16_t x, y, z1, z2; - float t, t2; - - x = TPRead(TP_READ_SEL(TP_CHAN_X, TP_MODE_12, TP_REF_DIFF, TP_PD_ON)); - y = TPRead(TP_READ_SEL(TP_CHAN_Y, TP_MODE_12, TP_REF_DIFF, TP_PD_ON)); - z1 = TPRead(TP_READ_SEL(TP_CHAN_Z1, TP_MODE_12, TP_REF_DIFF, TP_PD_ON)); - z2 = TPRead(TP_READ_SEL(TP_CHAN_Z2, TP_MODE_12, TP_REF_DIFF, TP_PD_ON)); - t = ((float)x / 4096.0) * (((float)z2 / (float)z1) - 1); - t2 = (((float)x / 4096) * ((4096.0 / (float)z1) - 1)) - (1 - ((float)y / (float)4096.0)); + tp_getcoords(&x, &y, &z1, &z2, &t, &t2); printf("X = %5d Y = %5d Z1 = %5d Z2 = %5d T = %7.2f T2 = %7.2f\r\n", x, y, z1, z2, t, t2); } } else if (!strncmp("fl", cmd.buf, 2)) { @@ -173,8 +168,8 @@ "BPL" }; - printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", FlashReadID()); - status = FlashReadStatus(); + printf("Flash ID = 0x%04hx (expect 0xbf41)\r\n", flashreadid()); + status = flashreadstatus(); fputs("Status = ", stdout); for (unsigned int i = 0; i < sizeof(flstattbl) / sizeof(flstattbl[0]); i++) @@ -184,9 +179,9 @@ } printf("(0x%02x)\r\n", status); - FlashWriteStatus(0x00); + flashwritestatus(0x00); - status = FlashReadStatus(); + status = flashreadstatus(); fputs("Status = ", stdout); for (unsigned int i = 0; i < sizeof(flstattbl) / sizeof(flstattbl[0]); i++) @@ -199,112 +194,40 @@ lcd_setpwm(atoi(cmd.buf + 4)); } else if (!strncmp("timing", cmd.buf, 6)) { fputs("Timing..\r\n", stdout); - Delay(10000); + delay(10000); fputs("Done\r\n", stdout); + } else if (!strncmp("circ ", cmd.buf, 5)) { + uint16_t x, y, r, c; + char col; + + if (sscanf(cmd.buf, "circ %hu %hu %hu %c", &x, &y, &r, &col) != 4) { + printf("Unable to parse circ args\r\n"); + goto out; + } + + col = toupper(col); + if (col == 'R') + c = LCD_RED; + else if (col == 'G') + c = LCD_GREEN; + else if (col == 'B') + c = LCD_BLUE; + else if (col == 'L') + c = LCD_BLACK; + else + c = LCD_WHITE; + lcd_circle(x, y, r, c); } else if (!strncmp("zz", cmd.buf, 2)) { NVIC_SystemReset(); } else { printf("Unknown command\r\n"); } } + out: cmd.state = 0; } } -/* Setup hardware (USART etc) */ -void -Setup_HW(void) { - GPIO_InitTypeDef GPIO_InitStructure; - USART_InitTypeDef USART_InitStructure; - - /* RTC stuff */ - /* Enable PWR and BKP clocks */ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); - - /* Allow access to BKP Domain */ - PWR_BackupAccessCmd(ENABLE); - - /* Reset Backup Domain - * - * This resets the RTC etc back to 0 so probably only useful under user command - BKP_DeInit(); - */ - - /* Enable Low Speed External clock */ - RCC_LSEConfig(RCC_LSE_ON); - - /* Wait till LSE is ready */ - while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) - ; - - /* Select LSE as RTC Clock Source */ - RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); - - /* Enable RTC Clock */ - RCC_RTCCLKCmd(ENABLE); - - /* Wait for RTC registers synchronization */ - RTC_WaitForSynchro(); - - /* Wait until last write operation on RTC registers has finished */ - RTC_WaitForLastTask(); - - /* Wait until last write operation on RTC registers has finished */ - RTC_WaitForLastTask(); - - /* Set RTC prescaler: set RTC period to 1sec */ - RTC_SetPrescaler(32767); /* RTC period = RTCCLK/RTC_PR = (32.768 KHz)/(32767+1) */ - - /* Wait until last write operation on RTC registers has finished */ - RTC_WaitForLastTask(); - - /* Clock setup */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); - - /* Port configuration */ - /* Configure USART1 TX (PA.09) as alternate function push-pull */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* Configure USART1 RX (PA.10) as input floating */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - /* Enable GPIOB clock */ - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); - - /* Configure PB5 as output push-pull for LED */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - /* Configure PB15 as input pull-up push-pull for push button */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; - GPIO_Init(GPIOB, &GPIO_InitStructure); - - /* USART configuration */ - /* USART1 - 115200 8n1, no flow control TX & RX enabled */ - USART_InitStructure.USART_BaudRate = 115200; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_Init(USART1, &USART_InitStructure); - - /* Enable interrupts on receive data */ - USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); - - /* Enable USART */ - USART_Cmd(USART1, ENABLE); -} - /* Configure interrupt controller */ #ifdef VECT_TAB_RAM /* vector-offset (TBLOFF) from bottom of SRAM. defined in linker script */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spi.c Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,26 @@ +#include <stdint.h> +#include "spi.h" +#include "stm32f10x.h" + +uint8_t +SPI_WriteByte(uint8_t out) { + uint8_t in = 0; + + /* Wait until the transmit buffer is empty */ + while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET) + ; + + /* Send the byte */ + SPI_I2S_SendData(SPI1, out); + + /* Wait until a data is received */ + while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET) + ; + + /* Get the received data */ + in = SPI_I2S_ReceiveData(SPI1); + + /* Return the shifted data */ + return (in); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spi.h Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,2 @@ +uint8_t SPI_WriteByte(uint8_t out); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/touch.c Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,45 @@ +#include <stdint.h> + +#include "stm32f10x.h" +#include "delay.h" +#include "spi.h" +#include "touch.h" + +#define TP_SELECT() GPIO_ResetBits(GPIOB, GPIO_Pin_7) +#define TP_DESELECT() GPIO_SetBits(GPIOB, GPIO_Pin_7) + +uint16_t +tp_read(uint8_t type) { + uint16_t x = 0; + + /* Select device */ + TP_SELECT(); + + /* Do conversion */ + delay(10); + SPI_WriteByte(type); + + /* Read result */ + delay(10); + x = SPI_WriteByte(0x00); + x <<= 8; + x |= SPI_WriteByte(0x00); + delay(10); + + /* De-select device */ + TP_DESELECT(); + + /* Right justify 12 bit result */ + x = x >> 3; + return (x); +} + +void +tp_getcoords(uint16_t *x, uint16_t *y, uint16_t *z1, uint16_t *z2, float *t, float *t2) { + *x = tp_read(TP_READ_SEL(TP_CHAN_X, TP_MODE_12, TP_REF_DIFF, TP_PD_ON)); + *y = tp_read(TP_READ_SEL(TP_CHAN_Y, TP_MODE_12, TP_REF_DIFF, TP_PD_ON)); + *z1 = tp_read(TP_READ_SEL(TP_CHAN_Z1, TP_MODE_12, TP_REF_DIFF, TP_PD_ON)); + *z2 = tp_read(TP_READ_SEL(TP_CHAN_Z2, TP_MODE_12, TP_REF_DIFF, TP_PD_ON)); + *t = ((float)*x / 4096.0) * (((float)*z2 / (float)*z1) - 1); + *t2 = (((float)*x / 4096) * ((4096.0 / (float)*z1) - 1)) - (1 - ((float)*y / (float)4096.0)); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/touch.h Sat Feb 04 13:29:31 2012 +1030 @@ -0,0 +1,31 @@ +/* Touch controller (TSC2046N) defines */ +/* Mode/channel select defines */ +#define TP_READ_SEL(chan, mode, ref, pd) (0x80 | (((chan) & 0x07) << 4) | (((mode) & 0x01) << 3) | (((ref) & 0x01) << 2) | ((pd) & 0x03)) + +/* Channel select */ +#define TP_CHAN_TEMP0 0 +#define TP_CHAN_Y 1 +#define TP_CHAN_VBAT 2 +#define TP_CHAN_Z1 3 +#define TP_CHAN_Z2 4 +#define TP_CHAN_X 5 +#define TP_CHAN_AUX 6 +#define TP_CHAN_TEMP1 7 + +/* Mode select */ +#define TP_MODE_12 0 +#define TP_MODE_8 1 + +/* Reference type */ +#define TP_REF_DIFF 0 +#define TP_REF_SER 1 + +/* Power down mode */ +#define TP_PD_AUTO 0 +#define TP_PD_REF_OFF 1 +#define TP_PD_REF_ON 2 +#define TP_PD_ON 3 + +uint16_t tp_read(uint8_t type); +void tp_getcoords(uint16_t *x, uint16_t *y, uint16_t *z1, uint16_t *z2, float *t, float *t2); +