A simple alarm clock for the 1 day workshop presented by Skool and ARM Hungary in 2015.
Dependencies: Skool_wkshp_lib2015 mbed
Diff: mbed_clock.cpp
- Revision:
- 2:e084bab7bc1c
- Parent:
- 1:f76b625bd36e
- Child:
- 4:2c4154aae49e
--- a/mbed_clock.cpp Tue Sep 15 21:53:26 2015 +0000 +++ b/mbed_clock.cpp Thu Sep 24 15:49:20 2015 +0000 @@ -1,110 +1,41 @@ #include "mbed.h" #include "serial_lcd.h" +#include "pc_uart.h" +#include "rtc.h" +#include "keypad.h" +#include "menu.h" -DigitalOut myled(LED1); // On-board LED -Serial pc(SERIAL_TX, SERIAL_RX); // UART to communicate with PC DigitalOut R_LED(PA_10); // RED part of the RGB LED DigitalOut G_LED(PB_5); // GREEN part of the RGB LED DigitalOut B_LED(PA_9); // BLUE part of the RGB LED -DigitalOut LCD_RST(PB_10); // LCD RST -DigitalOut LCD_BL(PA_8); // LCD BackLight PwmOut speaker(PB_4); // Speaker -I2C i2c1(I2C_SDA, I2C_SCL); // I2C interface for LCD display - - -// Define your own keypad values -const char Keytable[] = { '1', '2', '3', 'A', // r0 - '4', '5', '6', 'B', // r1 - '7', '8', '9', 'C', // r2 - '*', '0', '#', 'D' // r3 - }; - // c0 c1 c2 c3 -const uint16_t rows[4] = {GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_8, GPIO_PIN_9}; -const uint16_t cols[4] = {GPIO_PIN_10, GPIO_PIN_11, GPIO_PIN_12, 0xFFFF}; -//const int nrows = 4; -const int ncols = 3; -const char BCD2HEX[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; -const char DOW[7][3] = { {'H',' ',' '}, {'K',' ',' '}, {'S','z','e'}, {'C','s',' '}, {'P',' ',' '}, {'S','z','o'}, {'V',' ',' '} }; - -uint32_t Index = 0xFF; -uint32_t new_key = 0; uint32_t Systck_cnt = 0; uint32_t Systck_evt = 0; -GPIO_InitTypeDef keypadInit; - -void Error(int err) { - switch (err) { - case 0: pc.printf("\033[44m\033[37mI2C communication error!\033[00m\r\n"); - break; - case 1: pc.printf("\033[44m\033[37mIncorrect calibration data error!\033[00m\r\n"); - break; - default: pc.printf("\033[44m\033[37mUnknown error!\033[00m\r\n"); - break; - } - while (1) { - myled = 1; - wait(0.1); - myled = !myled; - wait(0.1); - myled = !myled; - wait(0.1); - myled = !myled; - wait(2); - } -} -void EXTI9_5_IRQHandler(void) { - HAL_NVIC_DisableIRQ(EXTI9_5_IRQn); - if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_5) != 0) { - __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5); - HAL_GPIO_EXTI_Callback(0); - } else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_6) != 0) { - __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_6); - HAL_GPIO_EXTI_Callback(1); - } else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_7) != 0) { - __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_7); - HAL_GPIO_EXTI_Callback(4); - } else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_8) != 0) { - __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_8); - HAL_GPIO_EXTI_Callback(2); - } else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_9) != 0) { - __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_9); - HAL_GPIO_EXTI_Callback(3); - } - HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_RESET); // All cols are driven Low for resume IRQ operation - //NVIC_ClearPendingIRQ(EXTI9_5_IRQn); - HAL_NVIC_ClearPendingIRQ(EXTI9_5_IRQn); -} +extern uint32_t Index; +extern uint32_t new_key; +extern Serial pc; // UART to communicate with PC +extern DigitalOut myled; // On-board LED +extern FSM_State Main_FSM_States; +extern RTC_HandleTypeDef rtch; +extern RTC_TimeTypeDef rtc_time; +extern RTC_DateTypeDef rtc_date; +extern RTC_AlarmTypeDef rtc_alarm; +extern int tmp_date, tmp_sec; +extern int AlarmA_Enabled; +extern int AlarmA_triggered; -void HAL_GPIO_EXTI_Callback(uint16_t pin) { - int col; - int temp; +const float scala[38] = { 0.0f, 108.0f, 112.5f, 121.5f, 129.6f, 135.0f, 144.0f, 150.0f, 162.0f, 172.8f, 180.0f, 194.4f, 202.5f, + 216.0f, 225.0f, 243.0f, 259.2f, 270.0f, 288.0f, 300.0f, 324.0f, 345.6f, 360.0f, 388.8f, 405.0f, + 432.0f, 450.0f, 486.0f, 518.4f, 540.0f, 576.0f, 600.0f, 648.0f, 691.2f, 720.0f, 777.6f, 810.0f, + 864.0f }; - for (col = 0; col < ncols; col++) { - HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET); // All cols are driven High - HAL_GPIO_WritePin(GPIOC, cols[col], GPIO_PIN_RESET); // 1 col is driven Low - wait_ms(50); - temp = GPIOC->IDR; - temp = (temp & 0x0360); - switch (temp) { - case 0x0340: Index = col; - break; - case 0x0320: Index = 4 + col; - break; - case 0x0260: Index = 8 + col; - break; - case 0x0160: Index = 12 + col; - break; - default: Index = 0xFF; - break; - } - if (Index != 0xFF) { - break; - } - } - new_key++; -} +const uint32_t song[54][2] = { {16, 4}, {18, 4}, {20, 4}, {18, 4}, {16, 2}, { 0, 2}, {16, 4}, {18, 4}, {20, 4}, {18, 4}, {16, 2}, { 0, 2}, {20, 4}, {20, 4}, {21, 4}, {21, 4}, + {20, 4}, {20, 4}, {18, 2}, {20, 4}, {20, 4}, {21, 4}, {21, 4}, {20, 4}, {20, 4}, {18, 2}, {20, 4}, {18, 4}, {20, 4}, {21, 4}, {23, 4}, {21, 4}, + {20, 4}, {18, 4}, {20, 4}, {18, 4}, {20, 4}, {21, 4}, {23, 4}, {21, 4}, {20, 4}, {18, 4}, {16, 4}, {18, 4}, {20, 4}, {18, 4}, {16, 2}, { 0, 2}, + {16, 4}, {18, 4}, {20, 4}, {18, 4}, {16, 2}, { 0, 2} }; + void SysTick_Handler(void) { HAL_SYSTICK_Callback(); } @@ -114,226 +45,45 @@ Systck_evt++; } -int write_ser_lcd(unsigned char data, bool mode) { - char wd[2]; - int status; - - wd[0] = ((mode) ? 0x40 : 0x00); - wd[1] = (char)data; - status = i2c1.write(ST7032I_ADDR, wd, 2, false); - return status; -} - -void write_ser_text(unsigned char *text, uint32_t len) { - int i; - char wd[41]; - int status; - - wd[0] = 0x40; - for (i = 0; i < len; i++) { - wd[i + 1] = (char)text[i]; - } - status = i2c1.write(ST7032I_ADDR, wd, len + 1, false); - if (status != 0) { - Error(0); - } -} - -int init_ser_lcd(void) { - int status; - - LCD_RST = 0x0; // Generating Reset pulse - LCD_BL = 0x0; // BackLight off -// BL_LCD = 0.0; - wait_us(200); - LCD_RST = 0x1; - wait_ms(40); - status = write_ser_lcd(0x38, false); // Function set with IS = 0 - if (status != 0) { - Error(0); - } - wait_us(30); - status = write_ser_lcd(0x39, false); // Function set with IS = 1 - if (status != 0) { - Error(0); - } - wait_us(30); - status = write_ser_lcd(0x14, false); // Internal OSC frequency adjustment - if (status != 0) { - Error(0); - } - wait_us(30); - status = write_ser_lcd(0x79, false); // Contrast set - if (status != 0) { - Error(0); - } - wait_us(30); - status = write_ser_lcd(0x5C, false); // Power/Icon/Contrast control - if (status != 0) { - Error(0); - } - wait_us(30); - status = write_ser_lcd(0x6E, false); // Follower control - if (status != 0) { - Error(0); - } - wait_ms(200); -// wait_us(30); - status = write_ser_lcd(0x0C, false); // Display ON - if (status != 0) { - Error(0); - } - wait_us(30); - status = write_ser_lcd(0x01, false); // Clear display - if (status != 0) { - Error(0); - } - wait_us(30); - status = write_ser_lcd(0x06, false); // Entry mode set - if (status != 0) { - Error(0); - } - wait_us(30); - status = write_ser_lcd(0x02, false); // Home - if (status != 0) { - Error(0); - } - wait_us(30); - LCD_BL = 0x1; // BackLight ON -// BL_LCD = 0.5; - return 0; -} - int main() { uint32_t RGB_sel = 0; - uint32_t currentHclk; uint32_t dummy; - + int i; + float tone; - HAL_StatusTypeDef HAL_status; - HAL_LockTypeDef HAL_lock; - RTC_HandleTypeDef rtch; - HAL_RTCStateTypeDef rtc_state; - RTC_InitTypeDef rtc_init; - RTC_TimeTypeDef rtc_time; - RTC_DateTypeDef rtc_date; - RTC_AlarmTypeDef rtc_alarm; - int tmp_date, tmp_sec; - - char tt[16]; - + speaker = 0; R_LED = 1; G_LED = 1; B_LED = 1; - rtc_init.AsynchPrediv = 0x7F; - rtc_init.SynchPrediv = 0xFF; - rtc_init.HourFormat = RTC_HOURFORMAT_24; - rtc_init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; - rtc_init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; - rtc_init.OutPut = RTC_OUTPUT_DISABLE; - - rtc_date.Date = 13; - rtc_date.Month = 9; - rtc_date.WeekDay = 7; - rtc_date.Year = 15; - tmp_date = 13; - - rtc_time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; - rtc_time.Hours = 23; - rtc_time.Minutes = 58; - rtc_time.Seconds = 46; - rtc_time.StoreOperation =RTC_STOREOPERATION_SET; - tmp_sec = 0; - - rtch.Instance = RTC; - rtch.Init = rtc_init; - rtch.Lock = HAL_lock; - rtch.State = rtc_state; - - - __PWR_CLK_ENABLE(); - HAL_PWR_EnableBkUpAccess(); -// __HAL_RTC_WRITEPROTECTION_DISABLE(&rtch); - __HAL_RCC_LSE_CONFIG(RCC_LSE_ON); - __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); - dummy = RCC->BDCR; - dummy |= RCC_BDCR_RTCEN; - RCC->BDCR = dummy; -// __HAL_RCC_RTC_ENABLE(); - HAL_status = HAL_RTC_Init(&rtch); - pc.printf("HAL_Status: %d\r\n",HAL_status); - HAL_status = HAL_RTC_SetDate(&rtch, &rtc_date, FORMAT_BIN); - pc.printf("HAL_Status: %d\r\n",HAL_status); - HAL_status = HAL_RTC_SetTime(&rtch, &rtc_time, FORMAT_BIN); - pc.printf("HAL_Status: %d\r\n",HAL_status); - - __GPIOC_CLK_ENABLE(); - keypadInit.Pin = cols[0] | cols[1] | cols[2]; - keypadInit.Mode = GPIO_MODE_OUTPUT_OD; - keypadInit.Pull = GPIO_NOPULL; - keypadInit.Speed = GPIO_SPEED_MEDIUM; - HAL_GPIO_Init(GPIOC, &keypadInit); - - HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET); - HAL_GPIO_WritePin(GPIOC, cols[2], GPIO_PIN_RESET); - - keypadInit.Pin = rows[0] | rows[1] | rows[2] | rows[3]; - keypadInit.Mode = GPIO_MODE_INPUT; - keypadInit.Pull = GPIO_PULLUP; - HAL_GPIO_Init(GPIOC, &keypadInit); - keypadInit.Pin = rows[3]; - keypadInit.Mode = GPIO_MODE_IT_FALLING; - keypadInit.Pull = GPIO_PULLUP; - HAL_GPIO_Init(GPIOC, &keypadInit); - NVIC_SetVector(EXTI9_5_IRQn, (uint32_t)EXTI9_5_IRQHandler); - HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); + InitRTC(); + Init_keypad(); NVIC_SetVector(SysTick_IRQn, (uint32_t)SysTick_Handler); HAL_SYSTICK_Config(14400000); __enable_irq(); - pc.printf("\f\033[00m\033[33mmbed Clock with STM32F303RE NUCLEO board\033[00m\r\n"); - currentHclk = HAL_RCC_GetHCLKFreq(); - pc.printf("Current HCLK is: %d\r\n",currentHclk); -/* speaker.period(1.0/864.0); - speaker = 0.5; - wait(0.1); - speaker = 0.0; -*/ - init_ser_lcd(); write_ser_lcd(0x80, false); // set DDRAM addr to 0x00 - write_ser_text((unsigned char *)"Hello", 5); + write_ser_text((char *)" Alarm clock ", 16); write_ser_lcd(0xC0, false); // set DDRAM addr to 0x40, beginning of 2nd line - write_ser_text((unsigned char *)"Teszt",5); + write_ser_text((char *)"ARM SKOOL",16); - wait(2.0); + wait(3.0); write_ser_lcd(0x01, false); // Clear display - wait_us(30); + wait_us(1100); write_ser_lcd(0x06, false); // Entry mode set wait_us(30); - write_ser_lcd(0x80, false); // set DDRAM addr to 0x00, beginning of 1st line - wait_us(30); - write_ser_text((unsigned char *)"2015.09.12. Szo", 15); - write_ser_lcd(0xC0, false); // set DDRAM addr to 0x40, beginning of 2nd line - wait_us(30); - write_ser_text((unsigned char *)"23:24:56 23.2", 13); - write_ser_lcd(0xDF, true); + ShowTime(); + ShowDate(); while (1) { if (new_key != 0) { - if (Index < 0xFF) { - pc.printf("Key pressed: %c\r\n",Keytable[Index]); - write_ser_lcd(0xCF, false); // set DDRAM addr to 0x4F, end of 2nd line - write_ser_lcd(Keytable[Index], true); - } else { - pc.printf("Incorrect Index value!\r\n"); - } - if (new_key > 1) { - pc.printf("There were missed keys: %d\r\n",new_key); + if ((Index < 0xFF) & (Keytable[Index] == '#')) { + Main_FSM_States = IN_MENU; + MainMenu_Handler(); } new_key = 0; Index = 0xFF; @@ -344,47 +94,41 @@ HAL_RTC_GetTime(&rtch, &rtc_time, FORMAT_BCD); HAL_RTC_GetDate(&rtch, &rtc_date, FORMAT_BCD); if (rtc_time.Seconds != tmp_sec) { - tt[0] = BCD2HEX[((rtc_time.Hours & 0xF0) >> 4)]; - tt[1] = BCD2HEX[(rtc_time.Hours & 0x0F)]; - tt[2] = ':'; - tt[3] = BCD2HEX[((rtc_time.Minutes & 0xF0) >> 4)]; - tt[4] = BCD2HEX[(rtc_time.Minutes & 0x0F)]; - tt[5] = ':'; - tt[6] = BCD2HEX[((rtc_time.Seconds & 0xF0) >> 4)]; - tt[7] = BCD2HEX[(rtc_time.Seconds & 0x0F)]; - tt[8] = 0x00; // For printf - tmp_sec = rtc_time.Seconds; - write_ser_lcd(0xC0, false); - pc.printf("\033[3;0H"); // Move the cursur to the beginning of the 3rd line. - pc.printf(tt); - write_ser_text((unsigned char *)tt, 8); + ShowTime(); dummy = 0; if (rtc_date.Date != tmp_date) { - tt[0] = BCD2HEX[2]; - tt[1] = BCD2HEX[0]; - tt[2] = BCD2HEX[((rtc_date.Year & 0xF0) >> 4)]; - tt[3] = BCD2HEX[(rtc_date.Year & 0x0F)]; - tt[4] = '.'; - tt[5] = BCD2HEX[((rtc_date.Month & 0xF0) >> 4)]; - tt[6] = BCD2HEX[(rtc_date.Month & 0x0F)]; - tt[7] = '.'; - tt[8] = BCD2HEX[((rtc_date.Date & 0xF0) >> 4)]; - tt[9] = BCD2HEX[(rtc_date.Date & 0x0F)]; - tt[10] = '.'; - tmp_date = rtc_date.Date; - tt[11] = ' '; - tt[12] = DOW[rtc_date.WeekDay - 1][0]; - tt[13] = DOW[rtc_date.WeekDay - 1][1]; - tt[14] = DOW[rtc_date.WeekDay - 1][2]; - tt[15] = 0x00; // For printf - write_ser_lcd(0x80, false); - pc.printf("\033[4;0H"); // Move the cursur to the beginning of the 4th line. - pc.printf(tt); - write_ser_text((unsigned char *)tt,15); + ShowDate(); } } - + + if (AlarmA_triggered) { + AlarmA_triggered = 0; + ShowAlarmText(); + for (i = 0; i < 54; i++) { + if (song[i][0] > 0.0f) { + tone = float(1.0f/scala[song[i][0]]); + speaker.period(tone); + speaker = 0.5; + } else { + speaker = 0; + } + wait(float(1.0f/song[i][1])); + if ((new_key != 0) & (Index < 0xFF) & (Keytable[Index] == '#')) { + i = 54; + new_key = 0; + Index = 0xFF; + HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); + } + } + write_ser_lcd(0x01, false); // Clear display + wait_us(1100); + write_ser_lcd(0x06, false); // Entry mode set + wait_us(30); + ShowTime(); + ShowDate(); + } + if (Systck_cnt > 5) { switch (RGB_sel % 3) { case 0: @@ -419,6 +163,3 @@ Systck_evt = 0; } } - - -